Redis 有序集合(Zset / Sorted Set)
Redis 有序集合(Zset / Sorted Set)完整笔记
一、Zset 简介
Redis 有序集合 Zset 与普通集合 Set 类似,是不包含重复元素的字符串集合。
核心区别:
- 每个成员都关联一个
score(评分),集合会按照score从小到大排序。 - 成员是唯一的,但
score可以重复。 - 因为元素有序,所以可以快速根据
score或位置(排名)获取一个范围的元素。 - 底层类似 Java 中的
Map<String, Double>(存储value-score映射),又类似TreeSet(按score排序)。
二、常用命令
| 命令 | 语法 | 作用 |
|---|---|---|
zadd |
zadd <key> <score1> <value1> <score2> <value2> ... |
将一个或多个成员及其 score 值加入有序集合 |
zrange |
zrange <key> <start> <stop> [WITHSCORES] |
返回集合中索引在 [start, stop] 之间的元素;WITHSCORES 会同时返回 score |
zrangebyscore |
zrangebyscore <key> <min> <max> [WITHSCORES] [LIMIT offset count] |
返回 score 介于 min 和 max 之间的成员,按 score 升序排列 |
zrevrangebyscore |
zrevrangebyscore <key> <max> <min> [WITHSCORES] [LIMIT offset count] |
与 zrangebyscore 类似,改为按 score 降序排列 |
zincrby |
zincrby <key> <increment> <value> |
为元素的 score 加上指定增量(可正可负) |
zrem |
zrem <key> <value> |
删除集合中指定的成员 |
zcount |
zcount <key> <min> <max> |
统计 score 在 [min, max] 区间内的元素个数 |
zrank |
zrank <key> <value> |
返回成员在集合中的排名(从 0 开始) |
三、典型案例:实现文章访问量排行榜
# 添加数据:文章v1访问量1000,v2访问量2000,v3访问量3000
127.0.0.1:6379> zadd topn 1000 v1 2000 v2 3000 v3
(integer) 3# 按访问量从高到低取前10名,并显示分数
127.0.0.1:6379> zrevrange topn 0 9 withscores
1) "v3"
2) "3000"
3) "v2"
4) "2000"
5) "v1"
6) "1000"
四、底层数据结构
Zset 底层同时使用两种数据结构:
- Hash 表:关联
value和score,保证元素的唯一性,支持通过value快速查找score。 - 跳跃表(Skip List):用于按
score对元素进行排序,支持高效的范围查询。
跳跃表(跳表)简介
- 跳跃表是一种多层链表结构,通过“跳级”指针实现类似平衡树的查找效率,平均时间复杂度为 O(logN),实现远比红黑树简单。
- 查找示例:查找值为
51的元素- 普通有序链表:需要从
1开始依次遍历,共需 7 次比较。 - 跳跃表:通过多层指针“跳跃”查找,仅需 4 次比较即可找到元素,效率显著更高。
- 普通有序链表:需要从
五、典型应用场景
- 排行榜:如游戏积分、文章访问量、用户点赞数排名。
- 延时队列:将任务的执行时间作为
score,定时轮询获取score小于当前时间的任务并执行。 - 带权重的任务调度:根据任务优先级设置不同的
score,实现按优先级调度。
