Redis zset实现原理

Redis 的 Zset(有序集合)通过 ziplist 和 skiplist 实现,当元素数量较少、长度较短时使用 ziplist,否则采用 skiplist。skiplist 结合 map 存储成员与分数的映射,实现 O(1) 查找和 O(logN) 插入。skiplist 是一种并行有序链表,通过随机层数提高插入和查找效率,最大层数为 32 层。查找和插入过程涉及到 map 与 skiplist 的操作,删除则根据 value 从 map 和 skiplist 中移除。Zset 的排名由插入和删除时维护的 span 值计算得出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

zset的两种实现方式
ziplist:满足以下两个条件的时候

  • 元素数量少于128的时候
  • 每个元素的长度小于64字节

skiplist:不满足上述两个条件就会使用跳表,具体来说是组合了map和skiplist

  • map用来存储member到score的映射,这样就可以在O(1)时间内找到member对应的分数
  • skiplist按从小到大的顺序存储分数
  • skiplist每个元素的值都是[score,value]对

因为有了skiplist,才1能在O(logN)的时间内插入一个元素,并且实现快速的按分数范围查找元素

skiplist优势
skiplist本质上是并行的有序链表,但它克服了有序链表插入和查找性能不高的问题。它的插入和查询的时间复杂度都是O(logN)

skiplist原理
普通有序链表的插入需要一个一个向前查找是否可以插入,所以时间复杂度为O(N),比如下面这个链表插入23,就需要一直查找到22和26之间。

如果节点能够跳过一些节点,连接到更靠后的节点就可以优化插入速度:

先使用第2层链接head->7->19->26,发现26比23大,就回到19
再用第1层连接19->22->26,发现比23大,那么就插入到26之前,22之后
上面这张图就是跳表的初步原理,但一个元素插入链表后,应该拥有几层连接呢?跳表在这块的实现方式是随机的,也就是23这个元素插入后,随机出一个数,比如这个数是3,那么23就会有如下连接ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值