Redis 命令及数据类型 -- ZSet

摘要

ZSet 数据类型

  • Redis ZSet 是一种 带权重的有序集合,本质结构为:

1
2
3
4
5
6
key -> { member -> score }
# 说明
member:唯一,不可重复(String,二进制安全)
score:double 类型,用于排序
集合按 score 从小到大 排序
score 相同则按 member 的字典序(Lex)排序
  • ZSet = Set(去重) + 排序能力

  • ZSet 的核心特性

1
2
3
4
5
元素唯一
天然有序
支持范围查询
支持排名(rank)
支持按 score 增量更新
  • Redis ZSet 的理论最大长度为 2^32 - 1 = 4294967295,但实际业务中,元素数量 ≥ 10,000 就算 BigKey 了。

  • Redis ZSet 是实现排行榜、延迟队列和有序统计的首选数据结构,在“顺序 + 去重 + 查询效率”之间取得了极佳平衡。

  • 生产环境建议

1
2
3
4
5
ZSet 适合 排序 + 查询
score 设计要稳定、可扩展
定期裁剪(ZREMRANGEBYRANK / ZREMRANGEBYSCORE)
大 ZSet 避免全量遍历
删除大 ZSet 使用 UNLINK
  • SpringBoot 的 RedisTemplate<K,V> 中 ZSet 数据类型 的操作方法与 Redis 原生命令的对应关系如下:

  • 基础写入 / 删除 / 计数

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令 命令备注 / 推荐替代
添加元素(含 score) Boolean add(K key, V value, double score) ZADD key score member 新增返回 true
添加元素(仅不存在时) Boolean addIfAbsent(K key, V value, double score) ZADD key NX score member Redis ≥ 3.0
批量添加 Long add(K key, Set<TypedTuple<V>> tuples) ZADD key score member [score member ...] 返回新增数量
批量添加(仅不存在) Long addIfAbsent(K key, Set<TypedTuple<V>> tuples) ZADD key NX ...
删除成员 Long remove(K key, Object... values) ZREM key member [member ...] 返回删除数量
递增 score Double incrementScore(K key, V value, double delta) ZINCRBY key delta member
获取集合大小 Long size(K key) ZCARD key
获取集合大小(同义) Long zCard(K key) ZCARD key API 别名
  • 随机访问

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令 命令备注
随机获取成员 V randomMember(K key) ZRANDMEMBER key 不返回 score
随机获取不重复成员 Set<V> distinctRandomMembers(K key, long count) ZRANDMEMBER key count count > 0
随机获取可重复成员 List<V> randomMembers(K key, long count) ZRANDMEMBER key -count count < 0
随机获取成员及 score TypedTuple<V> randomMemberWithScore(K key) ZRANDMEMBER key WITHSCORES Redis ≥ 6.2
随机获取不重复成员及 score Set<TypedTuple<V>> distinctRandomMembersWithScore(K key, long count) ZRANDMEMBER key count WITHSCORES
随机获取可重复成员及 score List<TypedTuple<V>> randomMembersWithScore(K key, long count) ZRANDMEMBER key -count WITHSCORES
  • 排名 / score 查询

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令 备注
获取正序排名 Long rank(K key, Object o) ZRANK key member 从 0 开始
获取倒序排名 Long reverseRank(K key, Object o) ZREVRANK key member 从 0 开始
获取 score Double score(K key, Object o) ZSCORE key member
批量获取 score List<Double> score(K key, Object... o) ZMScore key member [member ...] Redis ≥ 6.2
score 区间计数 Long count(K key, double min, double max) ZCOUNT key min max
  • 区间查询(rank / score)

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令 备注
按 rank 查询 Set<V> range(K key, long start, long end) ZRANGE key start end 正序
rank = 元素在 ZSet 中按 score 排序后的下标位置(从 0 开始)
按 rank 查询(含 score) Set<TypedTuple<V>> rangeWithScores(K key, long start, long end) ZRANGE key start end WITHSCORES
按 score 查询 Set<V> rangeByScore(K key, double min, double max) ZRANGEBYSCORE key min max
按 score 查询(含 score) Set<TypedTuple<V>> rangeByScoreWithScores(K key, double min, double max) ZRANGEBYSCORE key min max WITHSCORES
score 分页 Set<V> rangeByScore(K key, double min, double max, long offset, long count) ZRANGEBYSCORE key min max LIMIT offset count
score 分页(含 score) Set<TypedTuple<V>> rangeByScoreWithScores(K key, double min, double max, long offset, long count) ZRANGEBYSCORE key min max WITHSCORES LIMIT offset count 按 score 升序分页,返回 member + score
倒序 rank 查询 Set<V> reverseRange(K key, long start, long end) ZREVRANGE key start end 按 rank 倒序(高 → 低)
倒序 rank(含 score) Set<TypedTuple<V>> reverseRangeWithScores(K key, long start, long end) ZREVRANGE key start end WITHSCORES 倒序 rank,返回 score
倒序 score 查询 Set<V> reverseRangeByScore(K key, double min, double max) ZREVRANGEBYSCORE key max min 注意:max 在前,min 在后
倒序 score(含 score) Set<TypedTuple<V>> reverseRangeByScoreWithScores(K key, double min, double max) ZREVRANGEBYSCORE key max min WITHSCORES 倒序 score,返回 score
  • 弹出元素(队列 / TopN 场景)

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令 备注
弹出最小 score TypedTuple<V> popMin(K key) ZPOPMIN key
批量弹出最小 score Set<TypedTuple<V>> popMin(K key, long count) ZPOPMIN key count
阻塞弹出最小 score TypedTuple<V> popMin(K key, timeout) BZPOPMIN key timeout
弹出最大 score TypedTuple<V> popMax(K key) ZPOPMAX key
批量弹出最大 score Set<TypedTuple<V>> popMax(K key, long count) ZPOPMAX key count
阻塞弹出最大 score TypedTuple<V> popMax(K key, timeout) BZPOPMAX key timeout
  • 区间删除

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令(完整)
按 rank 删除 Long removeRange(K key, long start, long end) ZREMRANGEBYRANK key start end
按 score 删除 Long removeRangeByScore(K key, double min, double max) ZREMRANGEBYSCORE key min max
按 lex 删除 Long removeRangeByLex(K key, Range<String> range) ZREMRANGEBYLEX key min max
  • 集合运算(ZSet 特有)

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令(完整) 备注
差集 Set<V> difference(K key, Collection<K> otherKeys) ZDIFF numkeys key [otherKey ...] Redis ≥ 6.2
差集(含 score) Set<TypedTuple<V>> differenceWithScores(K key, Collection<K> otherKeys) ZDIFF numkeys key [otherKey ...] WITHSCORES Redis ≥ 6.2
差集并存储 Long differenceAndStore(K key, Collection<K> otherKeys, K destKey) ZDIFFSTORE destination numkeys key [otherKey ...] Redis ≥ 6.2
交集 Set<V> intersect(K key, Collection<K> otherKeys) ZINTER numkeys key [otherKey ...] Redis ≥ 6.2
交集(含 score) Set<TypedTuple<V>> intersectWithScores(K key, Collection<K> otherKeys) ZINTER numkeys key [otherKey ...] WITHSCORES Redis ≥ 6.2
并集 Set<V> union(K key, Collection<K> otherKeys) ZUNION numkeys key [otherKey ...] Redis ≥ 6.2
并集(含 score) Set<TypedTuple<V>> unionWithScores(K key, Collection<K> otherKeys) ZUNION numkeys key [otherKey ...] WITHSCORES Redis ≥ 6.2
交集并存储 Long intersectAndStore(K key, Collection<K> otherKeys, K destKey) ZINTERSTORE destination numkeys key [key ...]
并集并存储 Long unionAndStore(K key, Collection<K> otherKeys, K destKey) ZUNIONSTORE destination numkeys key [key ...]
  • Lex(字典序,仅 score 相同)

Lex = Lexicographical Order(字典序),Lex 排序是按 member 的字符串字典序排序,而不是按 score。
只有当 ZSet 中所有元素的 score 相同时,Lex 排序才有意义
如果 score 不同,Redis 文档明确说明:结果不可预测

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令(完整) 备注
按 lex 查询 Set<V> rangeByLex(...) ZRANGEBYLEX key min max [LIMIT offset count] score 必须相同
倒序 lex 查询 Set<V> reverseRangeByLex(...) ZREVRANGEBYLEX key max min [LIMIT offset count]
lex 范围存储 Long rangeAndStoreByLex(...) ZRANGEBYLEX key min max [LIMIT offset count] → ZADD destKey Spring 封装
score 范围存储 Long rangeAndStoreByScore(...) ZRANGEBYSCORE key min max [WITHSCORES] → ZADD destKey Spring 封装

Lex 范围写法规则

写法 含义
[a ≥ a(包含)
(a > a(不包含)
[z ≤ z
+ 正无穷
- 负无穷

示例

1
2
# a ≤ member < d
ZRANGEBYLEX my:zset [a (d
  • 遍历

方法功能 方法redisTemplate.opsForZSet().xxx() Redis 原始命令(完整) 备注
游标扫描 Cursor<TypedTuple<V>> scan(K key, ScanOptions options) ZSCAN key cursor [MATCH pattern] [COUNT count] 推荐替代全量查询