从redis中学压缩——ziplist

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

  1. https://redisbook.readthedocs.io/en/latest/compress-datastruct/ziplist.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值