Redis内部数据结构总结(4)quicklist

redis对外的数据结构类型list的底层是quicklist

quicklist结构的定义

typedef struct quicklistNode {
    struct quicklistNode *prev;
    struct quicklistNode *next;
    unsigned char *zl;
    unsigned int sz;             /* ziplist size in bytes */
    unsigned int count : 16;     /* count of items in ziplist */
    unsigned int encoding : 2;   /* RAW==1 or LZF==2 */
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

typedef struct quicklistLZF {
    unsigned int sz; /* LZF size in bytes*/
    char compressed[];
} quicklistLZF;

typedef struct quicklist {
    quicklistNode *head;
    quicklistNode *tail;
    unsigned long count; /* total count of all entries in all ziplists */
    unsigned int len; /* number of quicklistNodes */
    int fill : 16; /* fill factor for individual nodes */
    unsigned int compress : 16; /* depth of end nodes not to compress;0=off */
} quicklist;


list支持的操作有

O(1)时间复杂度的
lpush:在左侧(即列表头部)插入
lpop:在左侧(即列表头部)删除
rpush:在右侧(即列表尾部)插入
rpop:在右侧(即列表尾部)删除

。。。

O(N)复杂度的
lindex:取某个位置的元素
linsert:在某个元素前后插入

。。。

一个有序列表,便于在两端追加和删除,而对中间位置存取的时间复杂度为O(N),这是一个双向链表所具有的特点。

         quicklist是一个由ziplist组成的双向链表。即quicklist的每一个节点都是ziplist。

         双向链表便于在两端进行push和pop,但是内存开销大:

         ①每个节点除保存数据之外还要保存两个指针。

         ②每个节点是单独的内存块,地址不连续,容易产生碎片。

 

         ziplist是一块连续的内存,存储效率高。但是修改不方便,每次数据变动都会引发realloc。尤其当ziplist很长时,realloc可能引发大量数据拷贝,近一步降低性能。


redis.conf的配置,表示系欸但最多包含几个数据项以及两端有多少个节点不压缩

list-max-ziplist-size -2
list-compress-depth 0


list-max-ziplist-size -2

采取正值的时候,表示节点最多包含几个数据项,即ziplist的长度。当取负值时,只能取-1~-5。

-5       每个节点ziplist的大小≤64KB字节(bytes)

-4                                              32

-3                                              16

-2                                                8(默认)

-1                                                4


list-compress-depth 0

因为列表很长的时候,最可能被访问的数据是两端的数据,为了节省内存可以压缩,参数表示quicklist两端不被压缩的节点个数,采用的压缩算法是LZF,一种无损压缩算法。

0                    不压缩(默认)

1                    quicklist的两端各有一个节点不压缩

...

n                    quicklist两端各有n个节点不压缩

你可能感兴趣的:(redis,reidis底层)