假设我有一组在线用户,可能包含20,000个条目。
接下来,假设每个用户都有他们自己关注的人员。
当用户登录时,我想检查以下列表中的哪些用户在线。
据我所见,有两种选择。
MULTI
ZINTERSTORE temp 2 online, following
ZRANGE temp 0 -1
DEL temp
MULTI EXEC
或者,我可以让列表用户跟随列表,然后遍历所有这些,为每个用户发起一个ISMEMBER调用:
SMEMBERS following
MULTI
foreach(following as fol){
ISMEMBER online fol
}
MULTI EXEC
这两种方法都不适合我。有没有更好的办法?如果我们想象一个普通用户在他们的下面的列表中有200个人,平均在线人数为20,000,那么如果不是上述哪一个是最合适的。
提前致谢。
答案 0 :(得分:2)
redis文档有助于正确理解您的问题解决方案。
查看第一个解决方案ZINTERSTORE
它需要时间复杂度: O(N * K)+ O(M * log(M))在最坏的情况下,N是最小输入有序集,K是输入有序集的数量,M是结果有序集中的元素数。当您需要比较人们对20,000名粉丝的比较与平均在线人数20,000次时,这将是至关重要的。
你的第二个解决方案要好得多。基于ISMEMBER( O(1)),在最坏情况下需要时间复杂度 O(N),其中N是最小的输入集。
有一个关于用户在线处理的有趣解决方案。您应该知道SETBIT
和GETBIT
- 如果您的用户有常规ID,它最多可以处理2 ^ 32位或用户。例如 - id为1的用户 - 第1位,345 - 第345位,依此类推。在这种情况下,您只有512mb的内存用于最多4,294,967,296个用户, O(1)时间复杂度来获取/设置它们的状态。并使用您的第二种方法将您排序的关注者与在线数据相交。
如果使用redis> = 2.6,您应该尝试使用LUA来优化第二类解决方案。例如,我的笔记本电脑上的200,000个密钥的map/reduce
仅需约720毫秒。然后少了
一组200个用户1ms。