redis底层数据结构之ZipList

ZipList是一种特殊的 “双端链表” ,由一系列特殊编码的连续内存块组成。可以在任意一端进行压入/弹出操作,且该操作的时间复杂度是O(1)

ZipList结构如下:

ZipList中的entry结构如下: 

 

 Entry中encodeing的编码分为字符串和整数两种:

        字符串:如果 encoding 是以“00” “01” “10” 开头,则证明contents是字符串,并且随着字符串长度的不同采用不同的编码方式:分别占用1个、2个或5个字节

如果 encoding 是以 “11” 开头,则证明 contents 中存放的是整数,此时encoding固定只占一个字节,根据不同的整数范围,定义了一些编码格式:

 其中,当存放的整数范围在 0-12时,甚至会省去contents的内存消耗

ZipList的连锁更新问题:

   ZipList 的每个Entry 都包含previous_entry_length 来记录上一个节点的大小,长度是 1 个或 5 个字节:

如果前一个节点的长度小于 254 个字节,则采用一个字节来记录

如果前一个节点的长度大于或等于 254个字节,则采用 5 个字节来记录,此时第一个字节为 0xfe ,后四个字节才是真实长度。

现在,假设有 N 个连续的,长度为 250-253 之间的 entry ,此时 previous_entry_length 属性用一个字节即可记录。

        此时 ,当有一个大小为 254 个字节的 entry 插入ZipList 最前面,此时会导致后面 entry 的 previous_entry_length 用 5 个字节来存储当前插入节点的大小,会导致后一个 entry 的大小变得大于或等于 254 个字节,从而引发连锁反应,后面的 entry 的previous_entry_length也会变大,entry 也变大,此时会频繁的进行数据迁移,申请内存,销毁动作,使性能受到很大影响。

在进行新增、删除操作时都可能导致连锁更新的发生 ,但是由于产生连锁更新的条件比较苛刻,所以发生的概率极低。根据连续的 250-253 字节的 entry 的个数不同,产生连锁更新的影响大小也会不同。

ZipList特性:

1.压缩列表可以看做是一个连接内存的 ”双向链表“ 

2.列表的节点之间并不是通过指针连接,而是记录上一个节点和本节点长度来寻址,内存占用较低。

3.如果列表数据过多,导致链表过长,查询性能会受到影响

4.增、删较大的数据时有可能发生连锁更新问题

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值