Redis-紧凑列表源码原理分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zanpengfei/article/details/86518824

1、Redis 5.0 增加了新的数据结构listpack,它是对ziplist结构的改进,优点是在存储空间上更加节省以及在结构上比ziplist更精简

1)结构体

struct listpack<T> {

    int32 total_bytes; // 占用的总字节数

    int16 size; // 元素个数

    T[] entries; // 紧凑排列的元素列表

    int8 end; // zlend 一样,恒为 0xFF

}

 

解析:在结构体上只是比ziplist少了一个zltail_offset字段,该字段是用于定位最后一个元素的位置,用于逆向遍历,而listpack是通过其他方式来定位该位置

2)元数据的结构体

struct lpentry {

    int<var> encoding;

    optional byte[] content;

    int<var> length;

}

解析:同ziplist结构体元素类似,不同点长度字段放在了元素的尾部,而且含义不同了,这里存储的是当前元素的长度,所以可以通过总字节大小(total_bytes)与最后一个字节大小来定位出最后一个元素的位置,另外encoding字段也不同,这里使用varint进行编码,而且元素长度的编码可以是1到5个字节

3)encoding字段设计

0xxxxxxx 表示非负小整数,可以表示0~127。

10xxxxxx 表示小字符串,长度范围是0~63,content字段为字符串的内容。

110xxxxx yyyyyyyy 表示有符号整数,范围是-2048~2047。

1110xxxx yyyyyyyy 表示中等长度的字符串,长度范围是0~4095,content字段为字符串的内容。

11110000 aaaaaaaa bbbbbbbb cccccccc dddddddd 表示大字符串,四个字节表示长度,content字段为字符串内容。

11110001 aaaaaaaa bbbbbbbb 表示 2 字节有符号整数。

11110010 aaaaaaaa bbbbbbbb cccccccc 表示 3 字节有符号整数。

11110011 aaaaaaaa bbbbbbbb cccccccc dddddddd 表示 4 字节有符号整数。

11110011 aaaaaaaa ... hhhhhhhh 表示 8 字节有符号整数。

11111111 表示 listpack 的结束符号,也就是0xFF

 

2、级联更新

listpack的设计彻底消灭了ziplist存在的级联更新行为,元素之间完全独立,不会因为某个元素的长度变长就导致后续元素内容受到影响

 

3、愿景:取代ziplist

listpack设计目的是为了取代ziplist,但是listpack在兼容性方面还存在一些问题而且ziplist使用范围比较广,替换起来比较复杂,所以目前只应用在新增加的数据结构(Stream)中。

猜你喜欢

转载自blog.csdn.net/zanpengfei/article/details/86518824