Skip to content
← 返回Redis列表
数据与原子性

Redis Sorted Set(有序集合) · 旧版兼容命令至6. 过期、持久化与生命周期 ​

返回分篇目录

本文按 Redis 8.2.10 核对编码与配置默认值;命令的引入版本另行标注。生产配置可能不同,可通过 CONFIG GET 查询。示例面向独立实验服务,运行结果和内存数字未在本次实测。

旧版兼容命令 ​

命令与用途示例与结果复杂度
ZRANGEBYSCORE
旧式分数区间查询
ZRANGEBYSCORE learn:{zset}:a 10 20 WITHSCORES
新代码用 ZRANGE ... BYSCORE。
O(log N+M)
ZREVRANGE
旧式倒序名次查询
ZREVRANGE learn:{zset}:a 0 1 WITHSCORES
返回 carol、bob;新代码用 ZRANGE ... REV。
O(log N+M)
ZREVRANGEBYSCORE
旧式倒序分数查询
ZREVRANGEBYSCORE learn:{zset}:a 30 20 WITHSCORES
上界在前;新代码用 ZRANGE ... BYSCORE REV。
O(log N+M)
ZRANGEBYLEX
旧式字典序查询
ZRANGEBYLEX learn:{zset}:lex [a [b
同分集合返回 a、b;新代码用 ZRANGE ... BYLEX。
O(log N+M)
ZREVRANGEBYLEX
旧式倒序字典序查询
ZREVRANGEBYLEX learn:{zset}:lex [c [b
返回 c、b;新代码用 ZRANGE ... BYLEX REV。
O(log N+M)
版本与复杂度补充

下表保留每条命令的引入版本、兼容状态及复杂度符号含义;复杂度不包含全部网络传输、内存分配和等待成本。

命令引入版本与状态复杂度说明
ZADD1.2.0每个成员 O(log N),N 为目标集合大小;多成员累加。
ZINCRBY1.2.0O(log N),N 为集合大小;阻塞等待时间另计。
ZSCORE1.2.0O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。
ZMSCORE6.2.0O(M),M 为指定或返回成员数。
ZCARD1.2.0O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。
ZRANDMEMBER6.2.0O(M),M 为指定或返回成员数。
ZSCAN2.8.0官方渐进遍历口径:单次 O(1),完整迭代 O(N);COUNT 只是提示,编码和结果数量影响耗时。
ZCOUNT2.0.0O(log N),N 为集合大小;阻塞等待时间另计。
ZLEXCOUNT2.8.9O(log N),N 为集合大小;阻塞等待时间另计。
ZRANK2.0.0O(log N),N 为集合大小;阻塞等待时间另计。
ZREVRANK2.0.0O(log N),N 为集合大小;阻塞等待时间另计。
ZRANGE1.2.0O(log N+M),N 为源集合大小,M 为返回或保存数;大 LIMIT 偏移还增加扫描成本。
ZRANGESTORE6.2.0O(log N+M),N 为源集合大小,M 为返回或保存数;大 LIMIT 偏移还增加扫描成本。
ZREM1.2.0O(M log N),N 为集合大小,M 为指定删除或弹出的成员数。
ZREMRANGEBYRANK2.0.0O(log N+M),M 为实际移除数。
ZREMRANGEBYSCORE1.2.0O(log N+M),M 为实际移除数。
ZREMRANGEBYLEX2.8.9O(log N+M),M 为实际移除数。
ZPOPMIN5.0.0O(M log N),N 为集合大小,M 为指定删除或弹出的成员数。
ZPOPMAX5.0.0O(M log N),N 为集合大小,M 为指定删除或弹出的成员数。
ZMPOP7.0.0O(K+M log N),K 为提供的键数,N 为选中集合大小,M 为弹出数。
BZPOPMIN5.0.0O(log N),N 为集合大小;阻塞等待时间另计。
BZPOPMAX5.0.0O(log N),N 为集合大小;阻塞等待时间另计。
BZMPOP7.0.0O(K+M log N),K 为提供的键数,N 为选中集合大小,M 为弹出数。
ZINTER6.2.0最坏 O(Nmin×K+M log M),Nmin 为最小输入集合大小,K 为集合数,M 为结果大小。
ZINTERCARD7.0.0最坏 O(Nmin×K),Nmin 为最小集合大小,K 为集合数。
ZINTERSTORE2.0.0最坏 O(Nmin×K+M log M),Nmin 为最小输入集合大小,K 为集合数,M 为结果大小。
ZUNION6.2.0O(T+M log M),T 为输入成员总数,M 为结果大小。
ZUNIONSTORE2.0.0O(T+M log M),T 为输入成员总数,M 为结果大小。
ZDIFF6.2.0最坏 O(T+(N−M) log N),T 为输入成员总数,N 为第一个集合大小,M 为结果大小。
ZDIFFSTORE6.2.0最坏 O(T+(N−M) log N),T 为输入成员总数,N 为第一个集合大小,M 为结果大小。
ZRANGEBYSCORE1.0.5;从 6.2.0 起弃用(兼容保留)O(log N+M),N 为源集合大小,M 为返回或保存数;大 LIMIT 偏移还增加扫描成本。
ZREVRANGE1.2.0;从 6.2.0 起弃用(兼容保留)O(log N+M),N 为源集合大小,M 为返回或保存数;大 LIMIT 偏移还增加扫描成本。
ZREVRANGEBYSCORE2.2.0;从 6.2.0 起弃用(兼容保留)O(log N+M),N 为源集合大小,M 为返回或保存数;大 LIMIT 偏移还增加扫描成本。
ZRANGEBYLEX2.8.9;从 6.2.0 起弃用(兼容保留)O(log N+M),N 为源集合大小,M 为返回或保存数;大 LIMIT 偏移还增加扫描成本。
ZREVRANGEBYLEX2.8.9;从 6.2.0 起弃用(兼容保留)O(log N+M),N 为源集合大小,M 为返回或保存数;大 LIMIT 偏移还增加扫描成本。

ZRANGE 默认按排名,没有 BYRANK;BYSCORE、BYLEX、REV、LIMIT 从 6.2 起支持。BYLEX 系列示例使用同分成员,不能把不同分数集合当成全局字典序索引。

通用键操作见键与过期时间,这里集中列出类型自身的命令。

3. 底层编码与内存 ​

小 ZSet 使用 listpack,超出条件后使用 skiplist 编码,对应跳表加字典:跳表支持排序和范围查询,字典支持成员定位。因此底层表示的查找成本也要区分操作。

8.2.10 默认 zset-max-listpack-entries 128、zset-max-listpack-value 64(成员字节长度)。超过任一条件可触发转换;不要把 128 当成集合最大容量,也不要假设删除成员后一定恢复紧凑编码。

编码与内存怎么测 ​

在独立实验实例准备教学键,再读实际状态;下列是测量方法,本次未运行或填写测量数字:

text
ZADD learn:types:rank 10 alice 20 bob
OBJECT ENCODING learn:types:rank
MEMORY USAGE learn:types:rank

固定键名、元素字节长度、Redis 版本和分配器,分别记录 1、10、100 个元素或不同值长度时的内存,再跨越编码阈值观察。单元素的增量开销可用相邻两次内存差估计,编码转换时不能套用线性平均;String/Bitmap 的横轴应使用字节数或最高位偏移。比较“一键多元素”和“多个独立键”时,把键名、对象、字典项和 TTL 管理开销一起计入。

MEMORY USAGE 默认对嵌套值采样,SAMPLES 0 会遍历所有嵌套值,仅在小型隔离实验中使用。其结果不等同于进程 RSS;大量键还会增加全局字典、分配器碎片和复制缓冲等成本,需结合 INFO memory。没有适用于所有版本的固定“每 key 几字节”。

依据:8.2.10 配置、对应类型实现、MEMORY USAGE。

4. 性能与阻塞风险 ​

ZSCORE 是 O(1),ZINCRBY/排名查询是 O(log N),大范围查询和批量清理会随结果规模增长。ZRANGE LIMIT 大偏移可能需要走过许多成员,不能只看最终返回 10 条。ZSCAN 可用于无序维护,但不提供名次顺序或快照。热点榜单需限制请求范围与清理批次。

常规命令执行主要占用主执行路径,耗时计算会拖慢同实例其他请求;网络 I/O、后台持久化和释放内存有其他线程/进程参与。命令复杂度不包含所有网络、分配、编码转换与客户端成本。

5. 原子性与并发 ​

ZINCRBY 原子增加分数;先查排名、再按结果修改涉及两次命令,需要 Lua 或 WATCH。匹配时“按分数取候选、校验、移除”应在同一脚本中完成,ZPOPMIN 不能替代任意分数区间匹配。原子领取延迟任务仍需要处理中租约和业务幂等来应对消费者崩溃。

MULTI/EXEC 保证排队命令连续执行,但执行时单条报错不会回滚其他已成功命令;WATCH 是乐观冲突检测,需要有界重试。Lua 也不会自动回滚运行错误前的写入,应先校验参数与类型,再修改状态。

6. 过期、持久化与生命周期 ​

只有整键 TTL,没有成员 TTL。滑动窗口与在线心跳需显式删除过旧 score;ZRANGE 是查询,不会自动清理。按赛季或业务日分键后设置保留期。大范围 ZREMRANGEBYSCORE 也会占用执行时间,应结合批量策略或按时间分桶。

大键会增加 RDB/AOF 重写、复制全量同步和恢复时的处理量,fork 写时复制还可能增加峰值内存。单次同步删除聚合对象可能阻塞;UNLINK 先摘除键,把主要回收工作移到后台,但总回收工作和内存压力仍存在,不能替代限长和拆分。

完成教学实验后,只清理自己创建的键,例如 UNLINK learn:types:rank。

继续阅读