三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Redis 有序集合(Zset / Sorted Set)

Redis 有序集合(Zset / Sorted Set)

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 介于 minmax 之间的成员,按 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 底层同时使用两种数据结构:

  1. Hash 表:关联 valuescore,保证元素的唯一性,支持通过 value 快速查找 score
  2. 跳跃表(Skip List):用于按 score 对元素进行排序,支持高效的范围查询。

跳跃表(跳表)简介

  • 跳跃表是一种多层链表结构,通过“跳级”指针实现类似平衡树的查找效率,平均时间复杂度为 O(logN),实现远比红黑树简单。
  • 查找示例:查找值为 51 的元素
    • 普通有序链表:需要从 1 开始依次遍历,共需 7 次比较。
    • 跳跃表:通过多层指针“跳跃”查找,仅需 4 次比较即可找到元素,效率显著更高。

五、典型应用场景

  • 排行榜:如游戏积分、文章访问量、用户点赞数排名。
  • 延时队列:将任务的执行时间作为 score,定时轮询获取 score 小于当前时间的任务并执行。
  • 带权重的任务调度:根据任务优先级设置不同的 score,实现按优先级调度。

← 返回列表