参考:redis zset 内部的实现原理_行走在江湖的博客-CSDN博客_redis的zset实现原理
1、可以想象,当链表足够长的时候,这种多层链表的查找方式能让我们跳过很多下层节点,大大加快查找的速度。
2、skiplist为了避免这一问题(新增/删除 为O(n)较低的时间复杂度),它不要求上下相邻两层链表之间的节点个数有严格的对应关系,而是为每个节点随机出一个层数(level)
3、从上面skiplist的创建和插入过程可以看出,每一个节点的层数(level)是随机出来的,而且新插入一个节点不会影响其它节点的层数。因此,插入操作只需要修改插入节点前后的指针,而不需要对很多节点都进行调整。这就降低了插入操作的复杂度。实际上,这是skiplist的一个很重要的特性
4、skiplist,指的就是除了最下面第1层链表之外,它会产生若干层稀疏的链表,这些链表里面的指针故意跳过了一些节点(而且越高层的链表跳过的节点越多)。这就使得我们在查找数据的时候能够先在高层的链表中进行查找,然后逐层降低,最终降到第1层链表来精确地确定数据位置。在这个过程中,我们跳过了一些节点,从而也就加快了查找速度。
5、实际应用中的skiplist每个节点应该包含key和value两部分。前面的描述中我们没有具体区分key和value,但实际上列表中是按照key(score)进行排序的,查找过程也是根据key在比较。
6、MaxLevel = 32,最大层数
7、实际上,Redis中sorted set的实现是这样的:
当数据较少时:sorted set是由一个ziplist来实现的。
当数据较多时:sorted set是由一个 "dict + 一个skiplist" 来实现的。简单来讲,dict用来查询数据到分数的对应关系,而skiplist用来根据分数查询数据(可能是范围查找)。
8、第1层链表不是一个单向链表,而是一个双向链表。这是为了方便以倒序方式获取一个范围内的元素
9、补充:
【有序集合】
【本质上是集合,所有元素不能重复】
【分数可以重复(相同时根据value字典排序),value不能重复】
【支持根据socre的范围查找】