@
Livid "这次的解决方法是,需要用到 KEYS 的地方,其实是我们目前的在线人数统计,现在这个地方已经加上了缓存,所以对 KEYS 的调用就大大减少了。"
这么看起来,你只是减少了 KEYS 的调用次数,可能就是加入缓存,每3,5分钟 keys() 一次。
我认为这样的做法还不够优雅,对你现在说的这个需求,以下是我的做法:
引入 Sorted sets,创建一个名字叫: user:online
当用户 user(id: user_id),进行一次页面操作的时候,timestamp_now 就是当前时间戳:
> ZADD user:online timestamp_now user_id
对于每一个用户的页面操作都是做这样的操作
* 最新的用户在线列表(精确列出在线用户,以下统计前 1000 个在线用户,按照时间戳逆序)*:
> ZREVRANGE 0 1000
1) user_id_1
2) user_id_2
...
* 统计 5 分钟内的用户数(其实在线是个虚幻的概念,只能说 x 分钟内活跃认为在线)*
> ZCOUNT myzset (timestamp_5_minutes_ago timestamp_now
* 定期清除 x 分钟内没有活跃的用户,控制 Sorted sets 的长度 *
> ZREMRANGEBYSCORE myzset -inf (timestamp_10_minutes_ago
上面操作复杂度:O(log(N)+M) 这是可以控制的,并且数据非常及时和准确。
其实这是一个很好的面试题目。
广告:我需要前端工程师,设计师:
http://v2ex.com/t/115602