我想跟踪有多少用户在线,我使用Redis来解决此问题,因为一个或多个应用程序实例访问此缓存以显示状态。在每次新登录时,Redis都会使用用户ID在“online_users”键上更新,并在每次注销时删除用户。这种方法是否正确,如果不是如何构建这种方法以获得最佳性能,以及有点大的数据集?
"online_users" -> {
user_s23,user_1f3,user_1mn,user_xd3
}
用户信息在缓存中可用,是否将状态包含为另一个属性?
user_s23 {
name, id, profile_pic, type, etc, status:active/inactive
}
虽然这个2 approaches for tracking online users with Redis. Which one is faster?问题的答案比较了两种方法,但提到的第一个链接不可用,所以我无法理解其他背景。
答案 0 :(得分:12)
如果您只想知道:
1-有多少用户在线
2-用户在线
3-查找给定用户是否在线
您可以确保可以跟踪每次注销,所有用户调用注销请求,然后您可以使用set
并存储用户ID用户登录时进入该用户并在用户注销时删除用户ID(与您描述的方法相同)。
示例:
> sadd online_users user_a
(整数)1
> sadd online_users user_b
(整数)1
> scard online_users
(整数)2
> sismember online_users user_a
(整数)1
> srem online_users user_a
(整数)1
> smmbers online_users
1)“user_b”
所有这些操作都是O(1),除了smembers
是O(N)之外,您唯一的关注点和限制是用于存储这些数据的内存。提示是尝试为用户使用较小的密钥,如果不能,Redis已经压缩它们。
如果您无法确保跟踪注销,则可以使用问题的第二种方法“使用Redis跟踪在线用户的两种方法。哪一种更快?”。
要使用此方法,您需要跟踪用户的所有事件(不仅是登录),并使用时间戳将用户ID存储在不同的键上,例如:online_users_2014-02-20_10-01(在线用户at 2014年2月20日10:01)。
要回答目前有多少用户在线,您可以说,例如,如果用户在过去3分钟内发送了至少一个事件,则会将其视为在线用户。然后计算最后3组的并集,并在结果集上使用scard来查找有多少用户在线。
这种方法要贵得多,因为sunion
是O(N)。并且最好在按键上添加超时(使用expire
命令)以保持帮助清理内存。
基于最后一种方法的另一种方法是在客户端添加一些逻辑,在后台每分钟发送一个PING事件,然后你可以跟踪这个事件,你就可以确保用户在那里套装在线。
答案 1 :(得分:5)
1)
在使用的性能和内存方面,我认为最好的方法是使用bitset结构,这样,每个用户都表示为一个位,Redis有很多命令(setbit,bitcount,bitop) ,getbit)使用这种结构。
使用此方法的唯一要求是每个用户都需要一个唯一的顺序ID。
示例:
1 - 用户43登录
> setbit online_users 43 1
(整数)0
2 - 用户57登录
> setbit online_users 57 1
(整数)0
3 - 在线用户总数
> bitcount online_users
(整数)2
4 - 用户43注销
> setbit online_users 43 0
(整数)1
5 - 在线用户总数
> bitcount online_users
(整数)1
6 - 检查用户57是否在线
> getbit online_users 57
(整数)1
2)可以在用户结构中设置一个新属性来跟踪用户状态,但可能更容易直接检查此值的online_users位集(使用getbit命令)。
3)可以找到第一个链接的缓存版本here
在内存和性能方面,使用bitset比其他问题的方法更好。
顺便说一句,我不会使用KEYS
命令的方法,因为当数据集很大时它可能成为瓶颈。
您可以在BITCOUNT Redis命令的文档页面上找到有关此方法的信息。