用Redis来搞用户登录那些统计数据,看看怎么快速又高效地算出登录情况
- 问答
- 2026-01-14 15:19:17
- 3
关于如何使用Redis来高效统计用户登录情况,核心思路是利用Redis内存数据库的极高读写速度和丰富的数据结构,来应对传统关系型数据库在高并发统计场景下的性能瓶颈,下面直接说明几种常见且实用的方法。
使用Bitmap进行海量用户活跃统计
Bitmap(位图)是处理大规模二值状态(如是/否,登录/未登录)统计的利器,它的原理非常简单:用一个很长的二进制位数组来表示状态,每个用户ID对应数组中的一个位(bit),用户ID为1001的用户,我们就看第1001位的值是0还是1,0代表未登录,1代表代表当天登录过。
具体操作上,我们可以为每一天创建一个独立的Bitmap键,键名可以设计为 user:login:20231027(表示2023年10月27日),当用户ID为1001的用户登录时,就执行一条Redis命令:SETBIT user:login:20231027 1001 1,这条命令的执行速度极快,几乎是常数时间复杂度。
它的巨大优势在于:

- 极其节省空间:存储4000万用户的登录状态,一个Bitmap只需要大约5MB的内存(4000万 bit / 8 / 1024 / 1024 ≈ 4.77MB),成本极低。
- 统计速度飞快:Redis提供了直接计算位图统计的命令。
- 想知道今天有多少用户登录了:
BITCOUNT user:login:20231027,命令会直接返回设置为1的位的总数,也就是当日活跃用户数(DAU)。 - 想知道用户1001在过去一周内哪几天登录过:可以对
user:login:20231021到user:login:20231027这7个Bitmap进行BITOP OR位运算,然后查看结果中1001位的值,或者直接对指定位置进行查询。 - 想知道连续7天都登录的用户数:可以通过
BITOP AND将7天的Bitmap进行“与”运算,得到的新Bitmap中所有为1的位,就代表了这7天都登录的用户,再用BITCOUNT统计总数即可。
- 想知道今天有多少用户登录了:
这种方法非常适合计算每日、每周、每月的活跃用户,以及用户的留存率等指标,参考《Redis实战》一书中对Bitmap的应用案例,它被广泛用于实现类似“用户签到”等功能,其效率是传统SQL的COUNT(DISTINCT user_id)语句无法比拟的。
使用HyperLogLog进行近似去重统计
我们并不需要一个绝对精确的登录用户数,而是可以接受一个带有微小误差的近似值,比如统计一个大型活动的独立访客数(UV),在这种情况下,HyperLogLog(HLL)是比Bitmap更节省空间的选择。
HLL是一种概率算法,它可以用极小的内存空间(每个HLL键大约只需要12KB)来统计最多2^64个不重复元素的基数(唯一值数量),无论你要统计1万个用户还是10亿个用户,它都只占用约12KB内存。

使用方法同样简单:
- 用户1001登录时,执行
PFADD login:20231027 1001。 - 获取当日登录用户数的近似值,执行
PFCOUNT login:20231027。
HLL的强大之处还在于支持合并操作,要统计本周的总登录用户数(去重),可以直接执行 PFMERGE login:this_week login:20231021 login:20231022 ... login:20231027,然后对合并后的键 login:this_week 执行 PFCOUNT,这在统计周活跃用户(WAU)、月活跃用户(MAU)时非常方便。
需要注意的是,HLL的统计结果有约0.81%的标准误差,这意味着如果实际值是10000,那么PFCOUNT的结果可能在9919到10081之间,但对于宏观的趋势分析,这个精度通常是可以接受的,根据Redis官方文档的描述,HLL是实现大规模去重计数的最佳选择之一。
使用Sorted Set进行实时排行榜和区间查询

如果我们不仅想知道用户是否登录,还想记录其登录的精确时间戳,并据此做排行榜或查询某个时间段内的登录用户,Sorted Set(有序集合)就派上用场了。
我们可以创建一个Sorted Set,比如键名为 user:login:timeline,当用户登录时,我们将当前的时间戳作为分数(score),用户ID作为成员(member)存入:ZADD user:login:timeline 1698393600 1001。
这样,我们可以实现以下功能:
- 最新登录用户榜:由于Sorted Set默认按分数升序排列,要获取最近登录的N个用户,可以使用
ZREVRANGE user:login:timeline 0 N-1 WITHSCORES命令进行逆序查询。 - 统计某个时间段的登录人数:比如想统计今天上午10点到12点之间的登录用户数,可以执行
ZCOUNT user:login:timeline 1698393600 1698400800(假设这两个数字是10点和12点的时间戳),这个命令会快速返回分数在该区间内的成员数量。 - 查询单个用户的最近登录时间:使用
ZSCORE user:login:timeline 1001即可获取用户1001的最后一次登录时间戳。
虽然Sorted Set占用的内存会比Bitmap大,但它提供了基于时间的排序和范围查询能力,非常适合需要时间维度的精细统计场景。
总结与组合使用
在实际项目中,这些方法往往不是孤立的,而是根据业务需求组合使用:
- 用 Bitmap 来精确、低成本地计算每日活跃和留存。
- 用 HyperLogLog 来宏观、高效地统计大盘的去重用户量。
- 用 Sorted Set 来记录详细登录流水,实现排行榜和精准时间区间查询。
可以将Redis计算出的结果定期持久化到MySQL等关系型数据库中,用于长期存储和更复杂的离线分析,这样既利用了Redis的性能优势,又保证了数据的可靠性,这种架构在互联网公司中非常普遍,是处理高并发用户行为统计的有效方案。
本文由歧云亭于2026-01-14发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/80619.html
