【Redis面试高频】- zset的底层数据,如何实现呢?
有序集合的编码可以是ziplist
或者skiplist
。当有序集合保存的元素个数小于128个,且所有元素成员长度都小于64字节时,使用ziplist
编码,否则,使用skiplist
编码。
zset-ziplist
ziplist
编码的有序集合使用压缩列表作为底层实现,每个集合元素使用两个紧挨着一起的两个压缩列表节点表示,第一个节点保存元素的成员(member),第二个节点保存元素的分值(score)。
压缩列表内的集合元素按照分值从小到大排列。如果我们执行ZADD price 8.5 apple 5.0 banana 6.0 cherry
命令,向有序集合插入元素,该有序集合在内存中的结构如下:
zset-skiplist
skiplist
编码的有序集合对象使用zset
结构作为底层实现,一个zset
结构同时包含一个字典和一个跳跃表。
typedef struct zset {
zskiplist *zs1;
dict *dict;
}
zset
结构中的zs1
跳跃表按分值从小到大保存了所有集合元素,每个跳跃表节点都保存了一个集合元素。通过跳跃表,可以对有序集合进行基于score
的快速范围查找。zset
结构中的dict
字典为有序集合创建了从成员到分值的映射,字典的键保存了成员,字典的值保存了分值。通过字典,可以用O(1)
复杂度查找给定成员的分值。