ziplist是redis由一系列特殊编码内存块组成的列表
结构
结构如下
type ziplist struct {
h *header
es []*entry
end byte
}
type header struct {
// 整个ziplist所占用字节数
zlbytes uint32
// 到达ziplist表末尾偏移量
zltail uint32
// ziplist节点数量。最多记录2^16,超出部分只能遍历得出
zllen uint16
}
type entry struct {
// 保存上一节点的长度。若小于254字节,则只占1byte,否则第一个设为254,后面4字节记录实际长度
pre_entry_len []byte
// encoding和length共同决定数据类型。00、01、10开头分别代表小于2^6、小于2^14、小于2^32字节字符数组
// 11开头代表数字。比如11000000代表int16类型
encoding []byte
length []byte
// 实际数据
content []byte
}
主要就是在储存长度等的元信息针对短数据进行了压缩
操作
追加操作和普通的链表区别不大就是要多计算储存节点的前一个节点长度、编码、本节点长度以及更新ziplist所占用空间、偏移量、节点数量
插入则是要先为新节点扩大ziplist空间,然后设置新节点。接着,麻烦的是要去更新新节点的下一个节点元数据,那么如果运气不好的话,若长度超出了,还要再次进行扩容,那么再次进行扩容,又要更新下下个节点。因此,这是可能发生内存扩容的链式反应的
总结
总的来说ziplist就是在建立储存数据较小的情况下疯狂压缩元信息的储存空间,比如对于一个用一个byte能够表达的数据长度,就不会占用整个int的长度,当然坏处就是如果长度超过了一个byte能表达的,那么相比于直接用int的方式其实是会更加占用内存
并且这种压缩方式是建立在连续的内存空间中(猜测应该是为了节省指针带来的多余内存占用),那么一旦出现重新分配内存的情况,那么可能会引发连续的内存分配,那么这个性能就会相当差
Ref
- https://redisbook.readthedocs.io/en/latest/compress-datastruct/ziplist.html
634

被折叠的 条评论
为什么被折叠?



