Redis 命令及数据类型 -- ZSet
摘要
- 本文介绍 Redis ZSet 数据类型
- 本文基于
redis-7.4.7 - Redis官网:https://redis.io/
- Redis 命令文档:https://redis.io/docs/latest/commands/
ZSet 数据类型
-
Redis ZSet 是一种 带权重的有序集合,本质结构为:
1 | key -> { member -> score } |
-
ZSet = Set(去重) + 排序能力
-
ZSet 的核心特性
1 | 元素唯一 |
-
Redis ZSet 的理论最大长度为 2^32 - 1 = 4294967295,但实际业务中,元素数量 ≥ 10,000 就算 BigKey 了。
-
Redis ZSet 是实现排行榜、延迟队列和有序统计的首选数据结构,在“顺序 + 去重 + 查询效率”之间取得了极佳平衡。
-
生产环境建议
1 | ZSet 适合 排序 + 查询 |
-
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 | # a ≤ member < d |
-
遍历
| 方法功能 | 方法redisTemplate.opsForZSet().xxx() |
Redis 原始命令(完整) | 备注 |
|---|---|---|---|
| 游标扫描 | Cursor<TypedTuple<V>> scan(K key, ScanOptions options) |
ZSCAN key cursor [MATCH pattern] [COUNT count] |
推荐替代全量查询 |