用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. 4.设置静态IP

    由于Ubuntu重启之后,ip很容易改变,可以用以下方式固定ip地址 1.设置ip地址 vi /etc/network/interface # The loopback network interfa ...

  2. 第6章 运行Spark SQL CLI

    第6章 运行Spark SQL CLI Spark SQL CLI可以很方便的在本地运行Hive元数据服务以及从命令行执行查询任务.需要注意的是,Spark SQL CLI不能与Thrift JDBC ...

  3. 在laravel中遇到并发的解决方案

    1,在mysql中创建唯一索引,在代码中try catch mysql的1062错误 2.将存在并发的代码丢给队列异步处理.这种解决方案的问题是,接下来的代码不能依赖队列的处理结果 3.使用mysql ...

  4. selenium定位方法(二)

    selenium定位方法(二)  1.xpath定位:xpath是在XML中查找节点所在的路径的表达式 1)绝对路径的Xpath表达式 例:/html/body/div/div[1]/ul//li[3 ...

  5. 安卓手机没有twrp的情况,如何下刷入magisk并获得root权限.

    安装adb工具 https://dl.google.com/android/repository/platform-tools_r29.0.6-windows.zip 从以上地址下载,然后解压到任意目 ...

  6. Intelligence Beyond the Edge: Inference on Intermittent Embedded Systems

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! 以下是对本文关键部分的摘抄翻译,详情请参见原文. Abstract 能量收集技术为未来的物联网应用提供了一个很有前景的平台.然而,由于这些 ...

  7. ominigraffle实践之画精美流程图+自动导出Xcode工程类图

    背景 在平常阅读各种文章时,注意到有的文章中流程图做得特别漂亮.特别羡慕.于是去搜索了下,发现mac平台好评很高的是一款名为ominigraffle的软件.这款软件不仅可以画图,还可以导出Xcode工 ...

  8. 从零开始的SpringBoot项目 ( 二 ) 使用IDEA创建一个SpringBoot项目

    工欲善其事 , 必先利其器 . IntelliJ IDEA 2019.3.3 x64的安装与破解 下面详细说明下如何使用idea创建我们的第一个springboot项目: 首先打开idea主界面选择 ...

  9. javaScript高级含Es6

    JavaScript高级第01天笔记 1.面向过程与面向对象 1.1面向过程 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了. 1.2 ...

  10. Photon PUN 一 介绍

    有句话说的好 , 官网永远是最好的学习地方 . 虽然国内的资料不多 , 但是官网的资料还是很充足 , 这就带着英汉词典就着作阅读理解的劲头去官网学习吧 https://doc.photonengine ...