首页 > 其他 > 详细

Redis设计与实现 第 7 章 压缩列表

时间:2021-06-17 09:32:03      阅读:21      评论:0      收藏:0      [点我收藏+]

第 7 章 压缩列表

ziplist 是列表键和哈希表底层实现之一

当一个列表键只包含少量列表项,且每个列表项是小整数值或者长度比较短的字符串时会使用 ziplist

127.0.0.1:6379> rpush lst 1 3 5 10086 "hello" "world"
(integer) 6
127.0.0.1:6379> OBject encoding lst
"ziplist"

?

7.1 压缩列表的构成

节约内存,一系列特殊编码的连续内存块组成的顺序型数据结构

一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或一个整数值

技术分享图片

技术分享图片

例子:

技术分享图片

7.2 压缩列表节点的构成

每个压缩列表节点可以保存一个字节数组或者一个整数值

字节数组可以是以下一种

  • 长度小于等于 63 (2^6 - 1)字节的字节数组
  • 16383 (2^14 - 1)
  • 4294967295 (2^32 - 1)

整数可以是:

  • 4 位行,[0, 12] 的无符号整数
  • 1 字节的有符号整数
  • 3 字节的有符号数
  • int16_t
  • int32_t
  • int64_t

技术分享图片

7.2.1 previous_entry_length

previous_entry_length 字节为单位,记录压缩列表前一个字节的长度,本身长度可以是 1 字节或 5 字节

  • 如果前一节点长度小于 254 字节,则为 1 字节
  • 如果前一节点长度大于等于 254 字,则为 5 字节,该属性的第一字节会被设置为 0xFE (254)。后面四个字节则用来保存前一节点的长度

可以通过当前节点的起始地址来计算前一个节点的起始地址,压缩列表的从表尾向表头遍历操作就是使用这一原理的,

7.2.2 encoding

encoding 记录节点的 content 属性所保存数据的类型以及长度

  • 1 字节、2 字节、或 5 字节,值最高位是 00、01、10的字节数组编码:
    • 表示 content 保存的是字节数组,数组长度为去除最高两位后的其他位记录
  • 1 字节长,值最高位为 11:
    • content 保存的是整数值,值为去除最高两位后的其他位记录

技术分享图片

7.2.3 content

技术分享图片

7.2.4 连锁更新

技术分享图片

技术分享图片

假如 e1 - eN 都是 250-253 字节,添加新节点 new ,且大小大于 254 字节,此时 e1 的previous_entry_length 只是 1 字节,于是需要重新分配内存空间,e1 的总长度变化,可能超过 254 字节,于是 e2 变化,直到 eN

这种特殊情况下产生的连续多次空间扩展操作称之为“连锁更新”

同理,删除节点也可能引发连锁更新

连锁更新最坏情况下需要对压缩列表执行 N 次空间重分配操作,每次重分配操作的时间复杂度为 O(n),所以连锁更新最坏情况下是 O(n^2)

虽然时间复杂度高,但几率是佷低的

  • 压缩列表恰好多个连续的,长度介于 250 - 253 字节的节点
  • 出现连锁更新,但只要被更新的节点少,性能影响不大

ziplistPush 平均复杂度为 O(n)

7.4 压缩列表 API

技术分享图片

Redis设计与实现 第 7 章 压缩列表

原文:https://www.cnblogs.com/zephxu/p/14891623.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!