阅读 8

《Redis设计与实现》读书笔记(五)压缩列表

压缩列表存在的意义

压缩列表(ziplist)是列表键和哈希键的底层实现之一。

  • 当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。
  • 当一个哈希键只包含少量键值对(512),并且每个键值对的键和值要么就是小整数值,要么就是长度比较短的字符串(64),那么Redis就会使用压缩列表来做哈希键的底层实现。

压缩列表的构成

Redis为了节约内存而开发的,有连续内存块组成的顺序型数据结构。一个压缩列表包含任意多个节点(entry),每个节点可以保存一个字节数组或者一个整数值。 压缩列表的内存结构

<zlbytes><zltail><zllen><entry>...<entry><zlend>
复制代码

各个部分在内存上是前后相邻的,它们分别的含义如下:

<zlbytes>: 32bit,表示ziplist占用的字节总数(也包括本身占用的4个字节)。
<zltail>: 32bit,表示ziplist表中最后一项(entry)在ziplist中的偏移字节数。<zltail>的存在,使得我们可以很方便地找到最后一项(不用遍历整个ziplist),从而可以在ziplist尾端快速地执行push或pop操作。
<zllen>: 16bit, 表示ziplist中数据项(entry)的个数。zllen字段因为只有16bit,所以可以表达的最大值为2^16-1。这里需要特别注意的是,如果ziplist中数据项个数超过了16bit能表达的最大值,ziplist仍然可以来表示。那怎么表示呢?这里做了这样的规定:如果<zllen>小于等于2^16-2(也就是不等于2^16-1),那么<zllen>就表示ziplist中数据项的个数;否则,也就是<zllen>等于16bit全为1的情况,那么<zllen>就不表示数据项个数了,这时候要想知道ziplist中数据项总数,那么必须对ziplist从头到尾遍历各个数据项,才能计数出来。
<entry>: 表示真正存放数据的数据项,长度不定。一个数据项(entry)也有它自己的内部结构,这个稍后再解释。
<zlend>: ziplist最后1个字节,是一个结束标记,值固定等于255。
上面的定义中还值得注意的一点是:<zlbytes>, <zltail>, <zllen>既然占据多个字节,那么在存储的时候就有大端(big endian)和小端(little endian)的区别。
ziplist采取的是小端模式来存储

关注下面的标签,发现更多相似文章
评论