这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
ZSET 数据结构
新需求:排行榜
产品经理又来了:
【需求文档】排行榜功能
功能 1:热门文章榜
- 按点赞数排序
- Top 100
- 实时更新
功能 2:24 小时热榜
- 最近 24 小时发布文章
- 按点赞数排序
功能 3:本周热榜
- 本周发布文章
- 按点赞数排序
功能 4:作者榜
- 按文章获赞总数
- Top 100 作者
这就是排行榜需求。
ZSET 简介
什么是 ZSET?
Redis Sorted Set(有序集合):
- 类似 Set,不允许重复元素
- 每个元素关联一个分数(score)
- 按分数自动排序
- 支持范围查询
示例:
ZADD ranking 100 "article:1"
ZADD ranking 200 "article:2"
ZADD ranking 150 "article:3"
自动排序:
article:2 (200)
article:3 (150)
article:1 (100)
ZSET 特性
特性 1:自动排序
- 按分数从小到大排序
- 分数相同时按字典序
- 支持倒序查询
特性 2:唯一性
- 元素唯一
- 重复添加会更新分数
特性 3:高性能
- O(log N) 添加/删除
- O(log N) 范围查询
- O(1) 获取排名
特性 4:丰富操作
- ZADD:添加/更新
- ZINCRBY:增加分数
- ZRANGE/ZREVRANGE:范围查询
- ZRANK/ZREVRANK:获取排名
- ZCOUNT:统计范围内的元素数量
基础操作
点赞排行榜
实时更新排行榜
时间范围排行榜
24 小时热榜
本周热榜
作者榜
按文章获赞总数
性能优化
优化 1:限制排行榜大小
优化 2:定期清理
优化 3:缓存排行榜结果
课后练习
练习 1
ZSET 的时间复杂度是多少?为什么?
参考答案(3 个标签)
RedisZSET时间复杂度
ZSET 时间复杂度:
ZADD:O(log N)
- 插入/更新元素
- 需要调整排序树
ZINCRBY:O(log N)
- 原子性增加分数
- 需要调整排序树
ZRANGE/ZREVRANGE:O(log N + M)
- log N:找到起始位置
- M:返回 M 个元素
ZRANK/ZREVRANK:O(log N)
- 查找元素排名
- 需要遍历排序树
ZCOUNT:O(log N)
- 统计范围内的元素
- 需要查找范围边界
ZREMRANGEBYRANK:O(log N + M)
- log N:找到删除范围
- M:删除 M 个元素为什么是 O(log N):
ZSET 底层实现:
- 使用跳跃表(Skip List)
- 或使用字典树(Tree Map)
跳跃表结构:
- 多层索引
- 类似"快速通道"
- 查找时从高层开始
查找过程:
1. 从最高层开始
2. 快速跳过不相关的节点
3. 逐层下降
4. 找到目标元素
时间复杂度:O(log N)练习 2
如何实现”分页查询”排行榜?
参考答案(3 个标签)
Redis分页ZSET
方案:使用 ZREVRANGE
性能问题:深分页
问题:
- 查询第 1000 页(start=19980, end=19999)
- Redis 需要遍历前 19999 个元素
- 性能差
解决方案:
1. 使用游标分页(基于分数)
2. 限制最大页数(只显示前 100 页)
3. 缓存热门页练习 3
如何实现”排名变化”功能?
参考答案(3 个标签)
Redis排行榜实时更新
方案:记录排名历史
练习 4
如何实现”段位排行榜”(青铜、白银、黄金)?
参考答案(3 个标签)
排行榜分段游戏化
方案:多个 ZSET
练习 5
如何实现”排行榜实时推送”?
参考答案(3 个标签)
排行榜实时更新WebSocket
方案:WebSocket + Pub/Sub
思考题
-
如何处理”分数相同”的情况?
-
如何实现”年度榜单”、“月度榜单”?
-
如何优化排行榜的”并发更新”性能?
💡 提示:这些问题没有标准答案,建议结合实际情况深入思考。
