用redis实现计数器

社交产品业务里有很多统计计数的功能,比如:

  • 用户: 总点赞数,关注数,粉丝数
  • 帖子: 点赞数,评论数,热度
  • 消息: 已读,未读,红点消息数
  • 话题: 阅读数,帖子数,收藏数

统计计数的特点

  • 实时性要求高
  • 写的频率很高
  • 写的性能对MySQL是一个挑战

可以采用redis来优化高频率写入的性能要求。

redis优化方案一

对于每一个实体的计数,设计一个hash结构的counter:

//用户
counter:user:{userID}
-> praiseCnt: 100 //点赞数
-> hostCnt: 200 //热度
-> followCnt: 332 //关注数
-> fansCnt: 123 //粉丝数 //帖子
counter:topic:{topicID}
-> praiseCnt: 100 //点赞数
-> commentCnt: 322 //评论数 //话题
counter:subject:{subjectID}
-> favoCnt: 312 //收藏数
-> viewCnt: 321 //阅读数
-> searchCnt: 212 //搜索进入次数
-> topicCnt: 312 //话题中帖子数

类似这种计数器,随着产品功能的增加,也会越来越多,比如回复数,踩数,转发数什么的。

redis相关的命令

//获取指定userID的所有计数器
HGETALL counter:user:{userID} //获取指定userID的指定计数器
HMGET counter:user:{userID} praiseCnt hostCnt //指定userID点赞数+1
HINCRBY counter:user:{userID} praiseCnt

缺点:这样设计,如果要批量查询多个用户的数据,就比较麻烦,例如一次要查指定20个userID的计数器?只能循环执行 HGETALL counter:user:{userID}。

优点:以实体聚合数据,方便数据管理

redis优化方案二

方案二是用来解决方案一的缺点的,依然是采用hash,结构设计是这样的:

counter:user:praiseCnt
-> userID_1001: 100
-> userID_1002: 200
-> userID_1003: 332
-> userID_1004: 123
.......
-> userID_9999: 213 counter:user:hostCnt
-> userID_1001: 10
-> userID_1002: 290
-> userID_1003: 322
-> userID_1004: 143
.......
-> userID_9999: 213 counter:user:followCnt
-> userID_1001: 21
-> userID_1002: 10
-> userID_1003: 32
-> userID_1004: 203
.......
-> userID_9999: 130

获取多个指定userID的点赞数的命令变成这样了

HMGET counter:user:praiseCnt userID_1001 userID_1002

上面命令可以批量获取多个用户的点赞数,时间复杂度为O(n),n为指定userID的数量。

优点:解决了批量操作的问题

缺点:当要获取多个计数器,比如同时需要praiseCnt,hostCnt时,要读多次,不过要比第一种方案读的次数要少。一个hash里的字段将会非常宠大,HMGET也许会有性能瓶颈。

用redis管道(Pipelining)来优化方案一

对于第一种方案的缺点,可以通过redis管道来优化,一次性发送多个命令给redis执行:

$userIDArray = array(1001, 1002, 1003, 1009);

$pipe = $redis->multi(Redis::PIPELINE);
foreach ($userIDArray as $userID) {
$pipe->hGetAll('counter:user:' . $userID);
} $replies = $pipe->exec();
print_r($replies);

还有一种方式是在redis上执行lua脚本,前提是你必须要学会写lua。

redis实现计数器的更多相关文章

  1. Redis原子计数器incr

    一.前言在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试.这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流量 ...

  2. Redis原子计数器incr,防止并发请求

    转自:https://blog.csdn.net/Roy_70/article/details/78260826 一.前言在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当 ...

  3. Redis的使用模式之计数器模式实例

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/123.html?1455853785 Redis 是目前 NoSQL 领域 ...

  4. Redis非关系型数据库

    1.简介 Redis是一个基于内存的Key-Value非关系型数据库,由C语言进行编写. Redis一般作为分布式缓存框架.分布式下的SESSION分离.分布式锁的实现等等. Redis速度快的原因: ...

  5. redis实战笔记(5)-第5章 使用 Redis构建支持程序

    本章主要内容 1.使用Redis记录日 志 2.使用Redis实现计数器并进行数据统计 3.查询IP地址所属的城市与国家 4.服务的发现与配置   这一章将介绍如何使用Redis来帮助和支持系统的其他 ...

  6. Redis集群入门

    官方文章: https://redis.io/topics/cluster-tutorial#redis-cluster-configuration-parameters 本文永久地址: https: ...

  7. redis(7)LRU缓存

    一.LRU简介 LRU是Least Recently Used的缩写,即:最近最少使用. 它是内存管理中的一种页面置换算法,对于在内存中但是又不用的数据块,操作系统会根据哪些数据属于LRU而将其移除内 ...

  8. redis之进阶

    redis之进阶   redis redis介绍 redis的功能特性 1,高速读写 2,数据类型丰富 3,支持持久化 4,多种内存分配及回收策略 5,支持事务 6,消息队列.redis用的多的还是发 ...

  9. Redis基础知识、命令以及java操作Redis

    1 nosql的概念 sql:操作(关系型)数据库的标准查询语言 关系型数据库(rdbms):以关系(由行和列组成的二维表)模型为核心数据库,有表的储存系统.(mysql.oracle.sqlserv ...

随机推荐

  1. Jmeter 常用函数(31)- 详解 __iterationNum

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 获取当前线程的循环次数,跟线程组属性挂 ...

  2. 阿里云鼠标垫,云中谁寄锦书来,阿里云定制GIT指令集鼠标垫

    活动地址 云中谁寄锦书来 活动时间 2020.8.19-8.28 奖品 必得,每日200份,共2000份 参考答案 tips:单选选择以上都是,多选就是全选 云效DevOps包含哪些产品- ABCDE ...

  3. eclipse git提交项目以及down项目大致步骤

    down git项目步骤: 复制了url之后,import projects项目选中from git ,会出现如下截图,信息会自动填充 填好信息一直Next即可 完成之后,打开“Git Reposit ...

  4. 启动tomcat出现闪退的原因

    出现闪退的可能有几点: 1.没有安装jdk或者配置jdk是否配置成功 2.找不到jdk安装的路径 3.tomcat环境配置失败 如果是第二点原因(确保第一第三点配置都正确无误)找不到jdk路径的话,可 ...

  5. Gitlab安装使用

    Gitlab安装使用 1. 为什么要使用gitlab Git的优点多多这里就不详细介绍了: Git是版本控制系统,Github是在线的基于Git的代码托管服务: Github有个小缺陷 (也不能算是缺 ...

  6. lammps_data文件

    一.notes: 1.不在data文件里写“#”(注释),否则,容易出错: 2.前两行不用写东西(建议): 3.相互作用系数可以不用写在data里边(如pair_coeff等),可有可无,but fo ...

  7. Ajax、XMLHttpRequest、JSONP的区别

    来自2020年搜狗的笔试题,第一题就不会

  8. CSP 202006-1 线性分类器python实现

    思路 这题问题是对于这一群点和一条直线,我们也不知道直线上方的是A类还是直线下方的是A类.其实对于这个二分类问题,我们也没必要知道.我们只需要判断直线每一测的点是不是一类(A类或B类)就可以了. 至于 ...

  9. Android自动化测试,5个必备的测试框架

    Appium Appium是一个开源的移动测试工具,支持iOS和Android,它可以用来测试任何类型的移动应用(原生.网络和混合).作为一个跨平台的工具,你可以在不同的平台上运行相同的测试.为了实现 ...

  10. Eazfuscator.net 2020 虚拟化保护(Virtulization)机制分析

    一.前言与目标 周末接触了一款游戏They are billons即亿万僵尸,想添加一些新的玩法元素比如新的兵种进去, 打开dnspy看了下,发现是Eazfuscator.net的Virtulizat ...