Redis压缩列表中每个entry的具体内容数据结构是怎样的?

压缩列表(ziplist)中的每个entry(节点)用于存储一个键值对或集合元素,其具体内容结构由两部分组成:前置节点长度编码和节点内容。

  1. 前置节点长度编码(Previous Entry Length Encoding)
    每个entry的开始部分是用来记录前一个entry内容长度的,其编码方式是变长的,可以是1字节、2字节或5字节格式:
  • 1字节:如果前一个entry内容长度小于254字节,使用1字节表示,最左边的两位为00,剩下的6位表示长度。
  • 2字节:如果前一个entry内容长度在254到65535字节之间,使用2字节表示,第一个字节的高位为10,其余15位表示长度(最高位省略,因为已知是10)。
  • 5字节:如果前一个entry内容长度大于65535字节,使用5字节表示,第一个字节为0xf0,剩余的4字节表示长度。
  1. 节点内容(Entry Content)
    节点内容根据存储的数据类型和大小有所不同,可能包括:
  • 整数值(Integers):如果是整数值,根据其大小,可以以1字节、2字节、4字节或8字节表示。
  • 字符串值(Strings):字符串内容紧跟在长度编码后面,字符串的长度可以是任意大小,Redis会对小字符串进行优化,如果长度小于等于63字节,长度会包含在第一个字节中;如果长度稍大但仍满足一定条件,Redis会使用embstr(嵌入式字符串)结构来存储,节约内存;否则,字符串内容将作为一个独立的对象存在于内存中。 例如,一个entry存储了一个整数值,其内容结构可能是:
   | prev len encoding | integer content (1/2/4/8 bytes) |

如果存储的是一个小字符串,其内容结构可能是:

   | prev len encoding | string content (up to 63 bytes or embstr) |

总的来说,压缩列表通过巧妙的变长编码方式节省了存储空间,特别是对于小数据量和简单的数据类型,能够极大地提高内存利用率。而当数据量增大或数据类型变得复杂时,Redis会自动转换为更适合的存储结构,如双向链表。