Redis实战之:最近参与者功能的实现

最近PM扔过来一个需求,换成好理解的表达方式为,
获得论坛每个版面的最近参与者(当然我们的产品并不是论坛,不过原理相似),
参与者生成规则为:
在版面中发表帖子或者回复了帖子的用户;将这些用户按照活动时间降序排序,
得到前几位用户;保证获得的参与者是不一样的。

实现方案

看到这个需求,我的第一反映是,直接从数据库获取用户啊,简单粗暴,
后来在具体设计的时候仔细想了下,这种方式需要查询多个表,
拿到结果后还要综合排序以及去重,怎么想都觉得费力不讨好。

一计不成又生一计,那我用Redis实现就好了。
刚好Redis的有序集合可以完美解决排序以及去重的问题,而且速度也快。

具体操作

  • Redis中使用有序集合broad:{broad-id}存放参与者列表
  • 有序集合的KEY为参阅者的ID,SCORE为该参与者最后一次活动的时间戳
  • 用户进行发帖操作或者回帖操作时,使用ZADD broad:{broad-id} KEY {user-id} {timestamp}命令往有序集合中添加记录
  • 获取最近参与者时,使用ZREVRANGE broad:{broad-id} 0 {participant-number}命令获取最后活动的几位用户ID

可能的问题

我们有必要对有序集合中存储的记录个数保持警惕,当用户量不大的时候,比如10w用户量,
那么在最坏情况下一个版面的最近参与数据大小估算值为:

100000 * (4 + 4) bytes ~= 800KB

当用户量上升到1000w的时候,空间消耗为80MB,
也就是说,当用户量级到1000w时才需要对有序集合的空间大小引起重视,

解决方法:

  1. 使用脚本定期移除有序集合中的元素个数,只保留最近的几个记录
  2. 每次获取最近参与者/添加数据的时候同时判断有序集合中的元素个数,
    如果大于指定的阈值时,移除有序集合中的前面元素,这个阈值不能太大,
    否则一次要移除太多元素导致Redis响应过慢,太小会导致删除操作太频繁。