Redis 有序集合和集合一样也是 String 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储 40 多亿个成员)。
1 基本命令
- 插入
127.0.0.1:6379> ZADD score 50 zhangsan # 插入,其中 key 为 score, 50 为分数,zhangsan 为成员
(integer) 1
127.0.0.1:6379> ZRANGE score 0 -1 # 查看所有成员
1) "zhangsan"
127.0.0.1:6379> ZADD score 70 lisi 90 wangwu # 同时插入多个值
(integer) 2
127.0.0.1:6379> ZRANGE score 0 -1 # 查看所有值,默认是按照分数升序显示成员
1) "zhangsan"
2) "lisi"
3) "wangwu"
- 排序
127.0.0.1:6379> ZRANGEBYSCORE score -inf +inf # 指定 -inf(负无穷)到 +inf(正无穷)区间升序显示成员
1) "zhangsan"
2) "lisi"
3) "xiaoliu"
4) "wangwu"
127.0.0.1:6379> ZRANGEBYSCORE score -inf +inf withscores # 指定 -inf(负无穷)到 +inf(正无穷)区间升序显示成员并携带分数
1) "zhangsan"
2) "50"
3) "lisi"
4) "70"
5) "xiaoliu"
6) "80"
7) "wangwu"
8) "90"
127.0.0.1:6379> ZRANGEBYSCORE score 60 80 withscores # 指定分数区间升序显示成员并携带分数
1) "lisi"
2) "70"
3) "xiaoliu"
4) "80"
127.0.0.1:6379> ZREVRANGE score 0 -1 withscores # 按照分数在指定下标区间降序显示
1) "wangwu"
2) "90"
3) "xiaoliu"
4) "80"
5) "lisi"
6) "70"
7) "zhangsan"
8) "50"
- 统计个数
127.0.0.1:6379> ZRANGE score 0 -1
1) "zhangsan"
2) "lisi"
3) "xiaoliu"
4) "wangwu"
127.0.0.1:6379> ZCARD score # 统计集合中的个数
(integer) 4
127.0.0.1:6379> ZCOUNT score 70 90 # 统计指定分数区间的成员个数
(integer) 3
- 移除
127.0.0.1:6379> ZRANGE score 0 -1 withscores
1) "zhangsan"
2) "50"
3) "lisi"
4) "70"
5) "xiaoliu"
6) "80"
7) "wangwu"
8) "90"
127.0.0.1:6379> ZREM score wangwu # 移除指定成员
(integer) 1
127.0.0.1:6379> ZRANGE score 0 -1 withscores
1) "zhangsan"
2) "50"
3) "lisi"
4) "70"
5) "xiaoliu"
6) "80"
其余常用命令可以通过评论提醒,谢谢。
2 适用场景
-
延时队列
zset 会按 score 进行排序,如果 score 代表想要执行时间的时间戳。在某个时间将它插入 zse t集合中,它变会按照时间戳大小进行排序,也就是对执行时间前后进行排序。 -
排行榜
经常浏览技术社区的话,应该对 “1 小时最热门” 这类榜单不陌生。如何实现呢?如果记录在数据库中,不太容易对实时统计数据做区分。我们以当前小时的时间戳作为 zset 的 key,把贴子 ID 作为 member ,点击数评论数等作为 score,当 score 发生变化时更新 score。利用 ZREVRANGE 或者 ZRANGE 查到对应数量的记录。 -
滑动窗口限流
滑动窗口是限流常见的一种策略。如果我们把一个用户的 ID 作为 key 来定义一个 zset ,member 或者 score 都为访问时的时间戳。我们只需统计某个 key 下在指定时间戳区间内的个数,就能得到这个用户滑动窗口内访问频次,与最大通过次数比较,来决定是否允许通过。