Redis数据结构之压缩列表

压缩列表是Redis为节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者整数值。

压缩列表构成

压缩列表构成

  • zlbytes: 记录整个压缩列表占用的内存字节数,对压缩列表进行内存重分配,或者计算zlend位置时使用
  • zltail:记录压缩列表表尾节点距离压缩列表起始地址由多少字节,通过这个偏移量,程序无需遍历整个压缩列表就可以确定表尾节点的地址
  • zllen:记录压缩列表包含的节点数量
  • entryx:代表对应的节点
  • zlend:表尾末端标识

压缩节点构成

压缩列表节点

previous_entry_length

previous_entry_length顾名思义存储的是前置节点的长度,previous_entry_length可以是1个字节或者5个字节。

  • 如果前一个节点长度小于254字节,previous_entry_length属性长度为1字节,前一节点长度就保存在这个字节里面
  • 如果前一个节点长度大于等于254字节,previous_entry_length属性长度为5字节,会进行标识设置和保存前一个节点的长度
    节点的previous_entry_length属性记录了前一个节点的长度,所以可以通过指针运算,根据当前节点的起始地址计算出前一个节点的起始地址。压缩列表从表尾向表头的遍历操作就是使用的这一原理实现的,是要我们拥有了一个指向某个节点起始地址的指针,那么就可以通过这个指针及节点保存的previous_entry_length查询到前一个节点。依次回溯,就可以完成列表的逆向遍历。

encoding

encoding记录了节点content的保存数据的类型及长度

content

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

连锁更新

redis如果发生连续多次内存空间扩展成为连锁更新。

什么是连锁更新

每个节点的previous_entry_length保存着前一个节点的长度信息,如果前置节点发生变更时,previous_entry_length也会有可能变更。如果previous_entry_length长度发生变更,那么该节点的内存占用空间也会变更。如果本节点长度的变更,正好是后置节点的长度也在临界点(本节点长度更新后,节点长度大于254,且后置节点previous_entry_length发生变更,占用空间也由小于254变成了大于了254)发生空间占用变更。又再次引起其后置节点长度发生变化。

什么时候会发生连锁更新

如果某个节点的前置节点发生变更时,就可能发生长度的更新,所以压缩列表插入节点或者删除节点都要有可能引发连锁更新。
不过虽然引发连锁反应的代价很高,但是发生连锁反应的概率很低,他需要满足一下几个条件

  • 首先,压缩列表里恰好有多个连续的,长度介于250-253字节之间的节点,连锁更新才有可能被引发
  • 其次,即使出现连锁更新,如果节点数量不多,也不会对性能造成致命的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值