使用Redis实现榜单

一、前言

  1. 使用redis实现
  2. 基于直播间业务场景
  3. 不阐述详细实现细节

二、相关Redis数据结构和命令

Redis 集合(Set)

  1. Sismember 命令判断成员元素是否是集合的成员。

Redis 有序集合(sorted set)

  1. Zrevrank 命令返回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序。
  2. Zincrby 命令对有序集合中指定成员的分数加上增量 increment
  3. Zrevrangebyscore 返回有序集中指定分数区间内的所有的成员。有序集成员按分数值递减(从大到小)的次序排列
  4. Zremrangebyrank 命令用于移除有序集中,指定排名(rank)区间内的所有成员。

其他

  1. 查找特定前缀key:scan命令

三、如何实现

榜单保存

  1. 使用 Redis 有序集合(sorted set)保存榜单数据
  2. 如果是按时间排序的榜单,把时间戳存到score字段;如果是按礼物数量排序,把数量存到score;其他排序场景同理

榜单添加数据操作幂等

  1. 使用数据库日志表(唯一索引) (最严格可靠)
  2. 使用一个set保存所有的消息ID,并使用sismember防止重复处理(并发场景可能不幂等)

数据清理

  1. 使用一个set保存现有所有在线的房间榜单;定时任务检查房间是否在播,不在线的进行清理(同时可以监听房间下播时间)
  2. 保存一定数量的redis榜单:Zremrangebyrank 命令用于移除有序集中,指定排名(rank)区间内的所有成员
  3. 使用scan命令 查找特定前缀key的榜单,同1或2操作进行清理

四、扩展

  1. 房间榜单的标识是房间id有时可能不够,因为通过榜单有时是和本场开播挂钩的,同一个房间多次开播,可能导致不同场次的数据导致榜单错误。
    增加房间开播id标识可以解决。
  2. 老生常谈的哲学问题:二八定理。花费大量时间来得到较低的收益,实现时要从业务看是否值得。但不代表在做设计方案时不去考虑,这是严谨性的问题。
    按极端的方式考虑,实际实现按业务需要进行选择折中。