php redis 签到,如何利用 Redis 快速实现签到统计功能
@这是小豪的第十一篇文章
上篇文章 已经对 Redis 基础命令进行了一个大致的学习,接下来我们就需要解决 Issue “增加用户活跃度统计” 啦!
其实当我看到这个 Issue 的时候,我的第一反应是利用 MySql 来实现,创建一个签到表,记录用户 ID 和 签到时间,然后统计的时候从数据库中取出来然后聚合计算,完美,哈哈。
但是当看到要求说要用 Redis 位运算的时候,我就在想,为啥呢,仔细想了一哈,发现如果用 MySql 来实现的话虽然简单粗暴,但是也有弊端,比如我们想要做一些复杂的功能就不是太方便了,或者说不是太高性能了,比如,今天是连续签到的第几天,在一定时间内连续签到了多少天。另外一方面,如果按100万用户量级来计算,一个用户每年可以产生 365条记录,100万用户的所有签到记录那就有点恐怖了,查询计算速度也会越来越慢。
所以毅然选择 Redis ,下面给大家介绍一下究竟为啥选择它。
准备
大家知道 Redis 的字符串数据都是以二进制的形式存放的,所以说 Redis 的 Bit 操作非常适合处理这个场景,因为 Bit 的值为 0 或 1,用户是否打卡也可以用 0 或 1 来表示,我们把签到的天数对应到每个字节上,打卡了就是1,没打卡就是0,那么一个用户一年下来的记录就是 365 位的长度,100万用户一年只需要耗费大约 43 M 左右的存储空间就可以了,而且速度贼快,大伙可能会问,这个究竟是怎么计算来的,我们来看一下官方的解释:
在一台 2010MacBook Pro 上,offset 为2^32-1(分配512MB)需要~300ms,offset 为2^30-1(分配128MB)需要~80ms,offset 为2^28-1(分配32 MB)需要~30ms,offset 为2^26-1(分配8MB)需要8ms。
大概的空间占用计算公式是:( offset / 8 / 1024 / 1024 )MB
这里的 offset ,大家姑且当做用户 ID 来看,哈哈。
那么究竟如何去打卡呢,我们可以利用 setbit 命令来实现,setbit 的作用说的直白点就是:在你想要的位置操作字节值,比如说用户 3 在 3月13号 签到了,那么 setbit(20190313, 3 ,1) 就可以实现签到功能了,这里的 offset 就是3,同理,不同的用户不同的日期,改变对应的值就好了。
那么下面我们来实战一下:
实例
1. 实例化一个 Redis 连接
$redis = app('redis.connection');
2. 如何去设计 key 呢?
$dayKey = 'login:'.\now()->format('Ymd'); // 输出类似:login:20190310
// 普通写法
$dayKey = 'login:'.\date('Ymd',\time());
简单粗暴,清晰明了,哈哈。
所以我们大致的格式应该是这样子的:
3. 签到
setbit - SETBIT KEY_NAME OFFSET (Time complexity: O(1))
对 key 所储存的字符串值,设置或清除指定偏移量上的位 bit
$redis->setbit($dayKey, $this->user->id, 1);
可以看到在存储方面不仅耗费内存少,快,而且操作还方便,就这么一句话就搞定了,我当初也以为会是很复杂的操作,哈哈。并且它还有非常低的灵活高效的统计计算成本。
4. 统计一周内的签到数据
bitop - BITOP operation destkey key [key ...]
对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上
AND : 对一个或多个 key 求逻辑并
OR : 对一个或多个 key 求逻辑或
XOR : 对一个或多个 key 求逻辑异或
NOT : 对给定 key 求逻辑非
$redis->bitop('AND', 'threeAnd', 'login:20190311', 'login:20190312', 'login:20190313');
echo "连续三天都签到的用户数量:" . $redis->bitCount('threeAnd');
$redis->bitop('OR', 'threeOr', 'login:20190311', 'login:20190312', 'login:20190313');
echo "三天中签到用户数量(有一天签也算签了):" . $redis->bitCount('threeOr');
$redis->bitop('AND', 'monthActivities'', $redis->keys('login:201903*'));
echo "连续一个月签到用户数量:" . $redis->bitCount('monthActivities');
echo "当前用户指定天数是否签到:" . $redis->getbit('login:20190311', $this->user->id);
.....
是不是特别方便快捷的统计查询,哈哈,
结束语
从上面的例子中大家可以看到不管在存储上面还是在统计计算上面,位运算都比 mysql 的方式好太多。
至此,一个简单的签到统计功能就已经实现了,大家可以根据自己的需求扩展,不当的地方欢迎大家指正,哈哈。
本作品采用《CC 协议》,转载必须注明作者和本文链接
finecho # Lhao
php redis 签到,如何利用 Redis 快速实现签到统计功能相关推荐
- 利用HttpSessionListener实现网站在线人数统计功能
为什么80%的码农都做不了架构师?>>> 在网站中经常需要进行在线人数的统计.过去的一般做法是结合登录和退出功能,即当用户输入用户名密码进行登录的时候计数器加1,然后当用户点击 ...
- redis服务器信息统计,利用Redis统计网站在线活跃用户的方法
前言 在工作中我们经常遇到这样的需求,要对某个在线网站的活跃用户数量进行统计.这里我们以redis为例,说明一下其实现的过程. 实现方法 在Redis中存在bitmap这种数据类型,这种数据类型是建立 ...
- 利用jdt快速实现pmd的功能
jdt可以做语法树分析,并且支持visitor模式对代码进行分析.跟pmd的分析方式一样,我们只要实现 visitor接口即可实现一个插件. @Service("requestMapping ...
- 利用 Xposed 快速实现一个简易微信机器人
目标 当前微信网页版限制越来越多,考虑尝试在手机上实现类似机器人的功能.本文目的是利用 Xposed 快速实现简易机器人功能,包括获取好友发来的消息,以及回复消息.后续可以增加智能回复,比如接入图灵机 ...
- xposed微信长视频转发_利用 Xposed 快速实现一个简易微信机器人
目标 当前微信网页版限制越来越多,考虑尝试在手机上实现类似机器人的功能.本文目的是利用 Xposed 快速实现简易机器人功能,包括获取好友发来的消息,以及回复消息.后续可以增加智能回复,比如接入图灵机 ...
- 【美文保存】nosql数据库对比以及如何巧妙利用redis来提高效率?
1. MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的 ...
- 利用Redis一步步实现优惠券的最终秒杀方案
订单ID不能采用自增长的原因: 1.规律变化太明显.两天下单的ID的差值,能够计算出商城的订单量: 2.如果采用自增长,订单数据是会不断产生的,到时候要分表,但是每个表的ID都是从0开始增长的,这样I ...
- c#获取对象的唯一标识_在 Java 中利用 redis 实现分布式全局唯一标识服务
作者: 杨高超 juejin.im/post/5a4984265188252b145b643e 获取全局唯一标识的方法介绍 在一个IT系统中,获取一个对象的唯一标识符是一个普遍的需求.在以前的单体应用 ...
- 利用redis写webshell
redis和mongodb我之所见 最近自己在做一些个人的小创作.小项目,其中用到了mongodb和redis,最初可能对这二者没有深入的认识. 都是所谓的"非关系型数据库",有什 ...
最新文章
- linux下如何将mysql加入环境变量
- 8.15 12.13-12.16
- c# BindingSource的简单应用
- Git现实(一个)版本控制概述
- 做到这23条,你就成熟了!
- 根据表达式的值,选择field中的值
- ajax被token拦截,vue中封装ajax请求,并且拦截请求在请求头中添加token
- Re:从0开始的微服务架构:(一)重识微服务架构--转
- nginx添加对web status及status的每一项含义
- Error querying database. Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
- EMNLP 2020 | 基于超边融合的文本增强知识图谱开放域问答
- P1038 神经网络(拓扑排序)
- python怎么模拟浏览器交互_干货分享:python爬虫模拟浏览器的两种方法实例分析(赶紧收藏)...
- 安卓USB开发教程 四 安卓 AOA
- FBEC2021暨第六届金陀螺奖颁奖典礼盛大开幕
- ARMA模型的性质之ARMA模型
- easyUI 如何不跳转页面,只是加载替换center部分内容
- 史上最全的微服务知识科普
- phpstudy中php页面不识别php代码解决方法
- Easy2game使用