quicklist 虽然通过控制 quicklistNode 结构中压缩列表的大小和元素个数,来减少连锁更新带来的性能影响,但并没有完全解决连锁更新的问题

于是,Redis 5.0 新设计一个数据结构 listpack,目的是替代压缩列表,它最大特点是 listpack 中每个节点不再包含前一个节点的长度,完全不会有连锁更新的隐患

listpack 结构设计

listpack 采用了压缩列表的很多优秀设计,比如还是用一块连续的内存空间来紧凑地保存数据,并且为了节省内存,listpack 节点会采用不同的编码方式保存不同大小的数据

  • encoding:定义该元素的编码类型,会对不同长度的整数和字符串进行编码
  • content:实际存放的数据
  • lenencoding + content 的总长度

压缩列表的 entry 为什么要保存 prevlen?listpack 改成 len 之后不会影响功能吗?

压缩列表的 entry 保存 prevlen 是为了实现节点从后往前遍历,知道前一个节点的长度,就可以计算前一个节点的偏移量

listpack 一样可以支持从后往前遍历,可以从当前列表项起始位置的指针开始,向左逐个字节解析,得到前一项的 entry-len 值(源代码