Redis 数据结构之 zipList

数据结构

ziplist字段说明:

名称

说明

长度

zlbytes

记录当前ziplist结构的所有字节数,包含zlbytes的4个字节

4字节

zltail

记录当前最尾的一个节点距离起始的位置

4字节

zllen

记录当前的ziplist的entry个数

2字节

entry

ziplist中每一项数据,也是一个对象

由具体的编码决定大小

zlend

记录当前ziplist的结束,固定值为255

1字节

entry字段说明:

名称

说明

长度

previous_entry_length

前一项的字节长度

encoding

当前项的编码方式

content

实际存储的内容

previsous_entry_length: 如果当前的值小于254,则会以一个字节来存储数值(范围是0-253),相反,如果是大于等于254,则会以5个字节来存储,第一个字节固定为 0xFE (因为255是结束符),其余4个字段来存储具体数值。

encoding:取决于content字段的内容

string类型:以00/01/10开头

int 类型:以11 开头,再往下区分

当为 1111xxxx格式时(只代表0-12的数值),因为0000与1111是不能再使用了(实际是1-13),所以最终的数值要以xxxx-1作为实际的值

如 11111010 -> 对应存储的是整数 5

示例

zlbytes的值为15(以小端形式存储数据)

zltail 的值是12,表示最后一个索引是12

zlen 是2 ,entry的个数为2

entry1 第一个字节是0,因为是每一个元素,第二个字节是11110101,则代表的是0-12的整数,值为0101-1=2

entry2 第一个字节是00000010,记录的是前一个元素的长度2,encoding部分,为11111010 ,也是代表0-12的整数,值为1010-1=5

这时,如果插入新的数据 "hello world",则会产生以下新的数据

[02] [0b] [48 65 6c 6c 6f 20 57 6f 72 6c 64]

连锁更新

从ziplist的结构中,可以知道,当添加或是删除节点时,会因为要重新计算previous_entry_length的值,可能导致发生连锁更新的情况。

如果 entry1的previous_entry_length 只有1个字节,当新插入的节点的长度大于254时,因为entry1的previous_entry_length无法存储该数值,就需要将entry1的previous_entry_length长度更新为5个字节。

假设当前的entry1大小,再加上扩容后的4个字节,超过254时,则entry2的长度也要进行更新,则会一直更新下去,删除操作也是相同的问题。

对于每次的新增与删除,都需要进行空间分配,连锁更新的最坏的情况是O(N2),但一般只有当一个ziplist有连续的多个长度在250-253字节的节点时,才会出现这种情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值