Redis 的使用——排行榜实现
需求背景
项目中常把持续使用的数据放到缓存中,以便更快响应、减少数据库操作。排行榜就是一个典型场景——如果每次用户查询都去查数据库,性能会很差。
以基于用户好友的排行榜为例,直接查库需要:获取好友 ID → 判断授权 → 获取数据 → 整合,中间还有各种异常处理,请求量上来后体验堪忧。
核心思路
Redis 的 ZSet(有序集合)是实现排行榜的核心数据结构:
- 有序性:每个元素有一个分数(score),Redis 根据分数排序
- 唯一性:每个元素唯一,不允许重复
- 高效操作:支持 O(log N) 的插入、删除、查找,支持按分数范围分页查询
代码实现
添加数据到排行榜
1 |
|
获取指定用户排名
1 | public R getRanking(String userId) { |
获取整体排行榜
1 | public R getLeaderboard() { |
踩坑与思考
1. ZSet 的实现原理?
ZSet 底层基于跳表(SkipList)和哈希表实现,兼顾有序性和高效查找。
2. 用户独立排行榜如何更新?
如果每个用户有自己的好友排行榜,好友数据变化后不方便逐个更新。建议对好友列表做缓存(增删好友时更新),再配合 ZSet 或数据库查询获取实时数据。ZSet 更适合平台维度的整体排行,如积分榜、月度爱心榜等。
3. 排行榜过期时间怎么处理?
ZSet 只能对整个集合设置过期时间,无法针对单条数据。可以用定时任务(如每天 0 点或每月 1 号 0 点)清空旧排行榜,统计当天或当月的有效记录。历史数据可单独落表用于归档。
小结
- Redis ZSet 是实现排行榜的首选方案,简单高效
- 注意排名从 0 开始,取排名时
reverseRank + 1 - 排行榜过期结合定时任务即可实现按天/月轮换
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Alignm-ent!
