1、什么是压缩列表?
由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构。
一个压缩列表可以包含任意多个节点(entry), 每个节点可以保存一个字节数组或者一个整数值。
2、有什么好处?
节约内存
3、整体结构如何?
4、节点的结构
每个压缩列表节点可以保存一个字节数组或者一个整数值(说白了还是一个节点保存一个元素)
encoding和content 熟悉不?参考上一篇【整数集合】的笔记
previous_entry_length 必须要大书特书
因为节点的 previous_entry_length
属性记录了前一个节点的长度,
所以程序可以通过指针运算, 根据当前节点的起始地址来计算出前一个节点的起始地址。
5、压缩列表的数据结构总结
还记得压缩列表中的一个属性zltail么?记录了尾节点。
所以结论:压缩列表有类似于双向链表的功能。
可以从尾到头、从头到尾遍历。
只不过,压缩列表是一块连续内存,无需指针,用地址加减法就行。
6、先说说连锁更新
书中给出了一个极端的例子
这个列子的简单概括就是,previous_entry_length虽然存的是前一个节点的长度,但是保持了redis一贯的作风:不浪费一点内存。根据长度不同使用存储的字节数不通。这会导致一个问题,这个问题就发生在254这个临界值周围。
会因为新插入的大于254字节的节点导致连锁更新(因为内存是连续的,只能重新分配)
不过书中给出了解释:
7、总结
以上是书中的总结
不过我想说的是,上面这4点不是最重要的。
最重要的是一定要记住 previous_entry_length 这个属性
1、previous_entry_length 是 压缩列表能实现 从尾到头 遍历 的 关键
2、previous_entry_length 是 导致连锁更新 的 ”真凶“
记住了这个属性的特点和设定,那么压缩列表的数据结构和运行原理就记住了。