Redis数据结构实现原理—压缩列表

本文详细介绍了压缩列表,一种针对内存节省设计的数据结构,适用于包含小整数或短字符串的列表和键值对。它由zlbytes、zltail、zllen和entry节点组成,具有高效遍历原理和处理连锁更新的方法,尽管在特殊场景下复杂度较高,但整体上对性能影响不大。
摘要由CSDN通过智能技术生成

压缩列表

  压缩列表为节约内存而设计的一种特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点(entry),每个节点可以保存一个字节数组或一个整数值

应用

  • 当列表键只包含少量列表项,并且每项是小整数或长度比较短的字符串
  • 当hash键只包含少量键值对,并且hash的键和值都是比较小的整数或比较短的字符串

组成

zlbytezltailzllenentry1entryNzlend
  1. zlbytes:记录整个压缩列表占用的内存字节数;在对压缩列表进行内存重新分配或计算zlend的位置时使用
  2. zltail:记录压缩列表尾结点距离压缩列表起始地址有多少个字节,通过这个偏移量,程序无需遍历整个压缩列表就可以确定表尾节点的地址
  3. zllen:记录压缩列表包含的节点数量,当节点数量大于65535时,需要遍历列表
  4. entryX:压缩列表包含的各个节点,节点的长度由节点保存的内容决定
  5. zlend:用于标记压缩列表的末端

压缩列表节点entry又由以下三部分构成:

previous_entry_length:记录压缩列表前一个节点的长度,根据指针运算找出前一个节点的起始地址,该属性的长度可以是1字节或者5字节
encoding:记录节点值的类型和长度

编码编码长度content属性保存的值
110000001字节int16_t类型的整数
110100001字节int32_t类型的整数
111000001字节int64_t类型的整数
111100001字节24位有符号整数

content:负责保存节点的值,值的类型和长度由节点encoding属性决定

压缩列表遍历原理

  1. 我们拥有指向压缩列表表尾节点起始地址的指针p1
  2. 通过p1减去最后一个节点的previous_entry_length属性的值,得到了前一个节点起始地址

连锁更新

  恰好有a1至aN个节点现在都是长度介于250~253个字节之间的大小,previous_entty_length属性用1个字节存储前一个节点长度,这时插入一个new节点长度为255个字节到表头,这时a1节点的previous_entty_length属性需要用5个字节来表示。这时麻烦事来了,a1长度变为了大于等于254了,那么a2节点的previous_entty_length属性也要更新并重新分配内存,以此类推直到aN的节点都要更新。Redis把这种特殊情况下产生的连续多次空间扩展称为连锁更新。
  连锁更新最坏时间复杂度为O(N^2)。不过引发这种场景的概率很低,即使有连锁更新,节点数量不多对性能也不会造成太大影响。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值