使用Redis跟踪在线用户

时间:2014-02-19 11:00:54

标签: redis

我想跟踪有多少用户在线,我使用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?问题的答案比较了两种方法,但提到的第一个链接不可用,所以我无法理解其他背景。

2 个答案:

答案 0 :(得分:12)

如果您只想知道:

1-有多少用户在线

2-用户在线

3-查找给定用户是否在线

您可以确保可以跟踪每次注销,所有用户调用注销请求,然后您可以使用set并存储用户ID用户登录时进入该用户并在用户注销时删除用户ID(与您描述的方法相同)。

示例:

  • user_a登录:
  

> sadd online_users user_a

     

(整数)1

  • user_b登录:
  

> sadd online_users user_b

     

(整数)1

  • 有多少用户在线?
  

> scard online_users

     

(整数)2

  • user_a在线吗?
  

> sismember online_users user_a

     

(整数)1

  • user_a注销:
  

> 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命令的文档页面上找到有关此方法的信息。