用Redis怎么搞定用户在线状态那点事儿,记录活跃度其实没那么难
- 问答
- 2026-01-23 16:06:09
- 6
根据常见的Redis应用实践和网络技术文章思路整理)
用Redis怎么搞定用户在线状态那点事儿,记录活跃度其实没那么难,这事儿说白了,就是得解决两个核心问题:第一,怎么快速知道一个用户现在是不是在线;第二,怎么判断他最近一段时间活不活跃,传统做法老爱用数据库,比如用户一登录就在数据库里记个“在线”状态,一退出就改成“离线”,但这么干问题太大了,用户量一多,数据库就受不了,而且用户要是直接关浏览器或者App闪退,你压根不知道他啥时候走的,这个“在线”状态可能就一直挂着,成了“僵尸状态”。
Redis这玩意儿,因为它速度贼快,而且数据能放内存里,特别适合干这种需要频繁读写、对速度要求高的活儿,用它来管在线状态和活跃度,就跟用对了工具一样,事半功倍。
先说说怎么用Redis记录用户在线状态
最简单的想法就是,用户一登录成功,我就在Redis里存个标记,用个简单的key-value结构就行,key可以设计成 user:online:用户ID(user:online:12345),value随便设个值,比如1或者true都行,关键是,你得给这个key设置一个过期时间。
这个过期时间是个妙招,你想想,用户登录后,你给他这个在线标记设置一个过期时间,比如30分钟,如果用户在30分钟内有任何操作(比如点击页面、发消息),你就更新一下这个key的过期时间,让它重新计时30分钟,这招叫做“滑动过期”,如果用户正常退出,你就主动把这个key从Redis里删掉,但如果用户异常断线了(比如网络断了、手机关机),你也不用怕,30分钟一到,这个key自己就消失了,这个用户的状态自然就变成“离线”了。
这样一来,你查询用户是否在线就超级简单:用EXISTS命令查一下这个key在不在就行了,在就是在线,不在就是离线,这种方法非常轻量,效率极高。
那怎么记录和分析用户活跃度呢?
光知道在线离线有时候还不够,运营可能还想知道哪些用户最近比较活跃,日活”(DAU)、“月活”(MAU),这时候可以用Redis更厉害的数据结构——位图(Bitmap)。
位图你可以把它想象成一个很长的格子纸,每个格子代表一天(或者一小时,看你精度),每个格子只能记0或1,我们给每个用户分配一个唯一的数字ID(比如数据库自增ID),这个ID就对应位图里的偏移量。
举个例子,假设我们要记录每日活跃用户,我们每天创建一个位图,key就叫 dau:2024-06-15,如果一个用户ID是12345的用户今天登录了或者有操作了,我们就在这个位图上,把第12345个位置设为1,命令就是 SETBIT dau:2024-06-15 12345 1,这一步操作开销极小。
这样做有什么好处呢?
- 节省空间:一个用户哪怕ID很大,在位图里也只占一个比特位,存储几千万用户的日活数据也就几MB内存。
- 统计方便:一天结束后,我想知道今天有多少活跃用户,一个命令
BITCOUNT dau:2024-06-15就能直接算出来。 - 分析强大:我想知道连续7天都活跃的用户有多少,可以用位图的
BITOP命令(位运算),把7天的位图做“与”操作,得到的新位图里值为1的,就是连续活跃的用户,再用BITCOUNT统计就行,同样,计算某段时间内的总活跃用户(去重),可以用“或”操作,这些计算都在Redis内部完成,速度飞快。
还有一种思路:使用有序集合(Sorted Set)
如果你想记录得更细致一点,比如不仅记录用户是否活跃,还想知道他最后活跃的时间戳,方便做更灵活的判断(比如筛选出最近10分钟内活跃的用户),可以用有序集合。
创建一个有序集合,key比如叫 recently:active:users,成员的分数(score)就是用户最后一次活跃的时间戳(用Unix时间戳就行),成员就是用户ID,用户每次活跃,就用 ZADD recently:active:users 时间戳 用户ID 来更新,这个命令会自动更新分数(时间戳)。
要找出最近10分钟内活跃的用户,就用 ZRANGEBYSCORE recently:active:users (当前时间戳-600) +inf 命令,括号表示不包含临界值,你还要定期清理太旧的数据,可以用 ZREMRANGEBYSCORE 把比如一天前的数据删掉,避免集合无限变大。
总结一下
用Redis搞用户在线和活跃度,核心就是利用它快和数据结构丰富的特点。
- 在线状态:用普通的key-value加过期时间,实现简单高效的在线状态管理,还能自动处理异常离线。
- 活跃度统计:用位图,特别适合做大基数的、按时间的活跃用户统计,节省空间,计算能力强大。
- 精细活跃跟踪:用有序集合,可以跟踪每个用户最后活跃时间,实现更灵活的查询。
这些东西听起来可能有点绕,但实际用起来,代码量其实不大,关键是思路转变过来,别老想着用数据库去update和select,把这些频繁操作交给Redis,数据库的压力就小多了,系统的响应速度也会快上一大截,不同的场景可以选择不同的数据结构组合使用,不是非得只用一种。

本文由雪和泽于2026-01-23发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/84545.html
