redis中的zset(有序集)
什么是1。zset?
在redis官网看到的(/commands.html#sorted_set)。有兴趣的同学可以直接去看。
ZADD关键得分1值1得分2值2........
也就是说,可以添加yes分值组和值组,并且可以同时添加多个组。
?4.zset实现
在redis.conf中,有如下两个参数:
zset-max-zip list-entries 128
zset-max-ziplist-value 64
这两个条件都不满足,所以我们用ziplist压缩表来实现有序集。
如果满足这两个条件中的一个,排序集的内部实现将从ziplist转换为zset。
Zset-Max-ziplist-Entries 128,即当排序集合中的元素对超过128(存储了score和值的元素对,所以数据项为256)时,内部实现会从zip list转换为Zset。
Zset-max-ziplist-value 64,即任意值的长度超过64字节,内部实现将从ziplist转换为Zset。
Zset由dict和skiplist实现。
5.?Ziplist,即压缩列表
压缩列表是由连续内存组成的顺序数据结构。压缩列表可以包含任意数量的条目,每个条目可以包含一个字节数组或一个整数。
压缩后的链表头有三个字段:zlbytes、zltail和zllen分别代表链表的长度(整个链表所占的字节数)、链表尾部的偏移量(从尾部节点到起始地址的字节数)和链表中的条目数。
列表末尾还有一个zlend,表示列表结束。
6.skiplist
从上图的压缩列表可以看出,如果我们寻找第一个元素或者最后一个元素,可以直接通过头中三个字段的长度来定位。复杂度为O(1),但如果寻找其他元素,只能顺序寻找,复杂度为O(n)。为了解决这个问题,我们可以使用跳表。
在添加节点之前,也会对其进行查询以确定插入位置,然后完成插入操作。同时,将实现排序集合的排序。
跳表中新添加的节点不会影响其他节点的索引位置。因此插入操作只需要修改插入节点前后的指针,不需要修改所有节点,降低了插入的复杂度,因此跳表在插入性能上明显优于平衡树。
?7.ZSET的使用场景
需要排序的场景,比如top10热门文章或者排行榜。
对于消息的延迟发送,使用score来存储发送时间戳,任务定期扫描已排序的集合来确定发送时间。