目录
Redis中hash数据类型使用了两种编码格式:ziplist(压缩列表)、hashtable(哈希表) 在redis.conf配置文件中,有以下两个参数,意思为:当节点数量小于512并且字符串的长度小于等于64时,会使用ziplist编码。
- hash-max-ziplist-entries 512
- hash-max-ziplist-value 64
ziplist 是一个经过特殊编码的双向链表,旨在提高内存效率。 它存储字符串和整数值,其中整数被编码为实际整数而不是一系列字符。 它允许在 O(1) 时间内在列表的任一侧进行推送和弹出操作。 但是,由于每个操作都需要重新分配 ziplist 使用的内存,因此实际复杂性与 ziplist 使用的内存量有关。
ziplist 是一个特殊双向链表,不像普通的链表使用前后指针关联在一起,它是存储在连续内存上的。

entry 中包含有previous_entry_length、encoding、content等属性

第一中情况:一般结构
第二种情况:此时entry结构:
prevlen编码:当前一个元素长度小于254(255用于zlend)的时候,prevlen长度为1个字节,值即为前一个entry的长度,如果长度大于等于254的时候,prevlen用5个字节表示,第一字节设置为254,后面4个字节存储一个小端的无符号整型,表示前一个entry的长度;
encoding编码:
encoding的长度和值根据保存的是int还是string,还有数据的长度而定;
前两位用来表示类型,当为“11”时,表示entry存储的是int类型,其他表示存储的是string;
存储int时:
- |11000000| encoding为3个字节,后2个字节表示一个int16;
- |11010000| encoding为5个字节,后4个字节表示一个int32;
- |11100000| encoding 为9个字节,后8字节表示一个int64;
- |11110000| encoding为4个字节,后3个字节表示一个有符号整型;
- |11111110| encoding为2字节,后1个字节表示一个有符号整型;
- |1111xxxx| encoding长度就只有1个字节,xxxx表示一个0 - 12的整数值;
存储string时:
- |00pppppp| :此时encoding长度为1个字节,该字节的后六位表示entry中存储的string长度,因为是6位,所以entry中存储的string长度不能超过63;
- |01pppppp|qqqqqqqq| 此时encoding长度为两个字节;此时encoding的后14位用来存储string长度,长度不能超过16383;
- |10000000|qqqqqqqq|rrrrrrrr|ssssssss|ttttttt| 此时encoding长度为5个字节,后面的4个字节用来表示encoding中存储的字符串长度,长度不能超过2^32 - 1;
entry中的prevlen字段表示前一个entry的长度,有两种取值,1byte或者5byte.
当一个entry前边的entry的长度发生变化时,会导致需要增大entry 的prevlen字段的size 来存储前一个entry的长度,如果有连续多个entry的容量接近254时,就会发生多个entry的prevlen的size需要扩容,这时就发生所谓的级联更新。
这种更新本质是prevlen size的变化,它以下有两种情形,