redis 用户在线状态统计方案汇总

参考这篇文档中的评论

最近我也在研究这方面的问题,提供一些备选方案让大家参考。

方案 1 :

使用有序集合
每当用户上线时,执行以下操作:

ZADD("online_users", , ) 想要知道有多少人在指定的时间区间(比如一天或者一周)内上线过,

那么可以使用时间区间的起始时间戳和结束时间戳作为参数,

调用 ZCOUNT 命令: ZCOUNT("oneline_users", , ) 判断用户的 session 是否过期可以通过以下方法: user_online_timestamp = ZSCORE("online_users", ) return (user_online_timestamp+SESSION_EXPIRETIME) < now() 其中 SESSION_EXPIRETIME 为 SESSION 的有效期秒数。

这个方案的优点是信息齐全,能够通过有序集合的特性方便地执行区间操作( O(logN)),也可以快速地获取指定用户的登录时间( O(1))。缺点是耗费的内存比较大,并且需要手动删除有序集合中已经过期的用户信息。

方案 2 :使用 HyperLogLog

用户上线: PFADD("online_users", ) 获取在线人数: PFCOUNT("online_users") 这个方案的优点是非常节约内存,无论网站的用户数量有多大,一个 HyperLogLog 都只消耗 12 KB 内存。

当然,这个方案的缺点也非常明显: 1. 它无法获取用户的具体登录时间。 2. 因为 HyperLogLog 是一个概率算法,所以它无法准确地判断一个用户是否在线。 以上缺点都可以通过增加一个储存用户登录时间的 Hash 来解决,不过这一样一来,需要消耗的内存也会增加。

方案 3 :使用 bitmap

上线: SETBIT("online_users", , 1) 检查指定的用户是否上线: GETBIT("online_users" ) == 1 统计在线人数: BITCOUNT("online_users") 这个方案最有趣的地方,就是可以对多个 bitmap 执行聚合计算,从而计算出诸如“有多少个人连续一周都上线了(全勤)”、“这周一共上线了多少个人”、

“有多少人今天上线了但是昨天没上线”等问题: BITOP("AND", "one_week_both_online", "day_1_online", "day_2_online", ..., "day_7_online") # 计算一周都上线的人 BITOP("OR", "one_week_online_total", "day_1_online", ..., "day_7_online") # 计算这周一共有多少人上线 这个方案储存一个用户的在线信息只需要使用一个二进制位,对于用户数为 100 万的网站来说,使用这一方案只需要花费 125 KB 内存,而储存 1000 万的用户信息只需要花费 1.25 MB 。 虽然 bitmap 节约内存的效果不及 HyperLogLog ,但是使用 bitmap 可以准确地判断一个用户是否上线。对于想要尽量节约内存,但又需要准确地知道用户是否在线,又或者需要对用户的在线信息进行聚合计算的应用来说,这个方案是最佳之选。

结语

好的,关于统计在线用户的备选方案就介绍到这里,希望这些方案会给大家带来帮助和启发。 最后打个小广告,我正在写一本名为《 Redis 使用教程》的书,里面不仅对用户 SESSION 储存、用户在线统计等问题给出了详细的解法,还提供了实际可运行的 Python 代码,上面给出的一些方案在书中也有介绍,有兴趣的朋友可以关注一下: RedisGuide.com 非常感谢!

你可能感兴趣的:(redis 用户在线状态统计方案汇总)