Redis 快速链表| 小册免费学

740 阅读3分钟

Redis 早期版本存储 list 列表数据结构使用的是压缩列表 ziplist 和普通的双向链表 linkedlist,也就是元素少时用 ziplist,元素多时用 linkedlist。

而快速链表则是ziplist+linkedlist同时使用

image.png

快速列表

typedef struct quicklist {
    quicklistNode *head; // 头指针
    quicklistNode *tail; // 尾指针
    unsigned long count; //所有压缩列表的节点数量之和。       
    unsigned long len;   //快速列表节点数量。       
    int fill : QL_FILL_BITS; // 32 位机器上占 14 bit,64 位机器上占 16 bit,存放 list-max-ziplist-size 参数的值,用于设置压缩列表节点的大小。             /* fill factor for individual nodes */
    unsigned int compress : QL_COMP_BITS; /* depth of end nodes not to compress;0=off */
    unsigned int bookmark_count: QL_BM_BITS;
    quicklistBookmark bookmarks[];
} quicklist;

32 位机器上占 14 bit,64 位机器上占 16 bit,存放 list-compress-depth 参数的值,用于设置压缩深度。快速列表默认的压缩深度为 0,即不压缩。为了支持快速的 push/pop 操作,快速列表的首尾两个节点不压缩,此时压缩深度就是 1。如果压缩深度为 2,就表示快速列表的首尾第一个及第二个节点都不压缩。

  • bookmark_count:占 4 bit,
  • bookmarks 数组的长度。bookmarks:这是一个可选字段,快速列表重新分配内存时使用,不使用时不占用空间。

快速列表节点



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;
  • z1:数据指针,如果当前节点的数据没有压缩,它指向一个 ziplist 结构,否则,它指向一个 quicklistLZF 结构。
  • sz:表示 zl 指向的数据总大小,注意,如果数据被压缩了,其表示压缩前的数据大小。
  • count:占 16 bit,表示当前的快速列表节点中数据项个数。
  • encoding:表示 当前节点的数据是否被压缩,目前只有两种取值:1 表示没有压缩;2 表示被压缩了,且用的是 LZF 压缩算法。
  • container:略
  • recompress:当我们使用类似 lindex 这样的命令查看了某一项本来压缩的数据时,需要把数据暂时解压,这时就设置 recompress=1 做一个标记,等有机会再把数据重新压缩。

quicklist 内部默认单个 ziplist 长度为 8k 字节

quicklist 默认的压缩深度是 0,也就是不压缩。压缩的实际深度由配置参数list-compress-depth决定。为了支持快速的 push/pop 操作,quicklist 的首尾两个 ziplist 不压缩,此时深度就是 1。如果深度为 2,就表示 quicklist 的首尾第一个 ziplist 以及首尾第二个 ziplist 都不压缩。

文章末尾请带上以下文字及链接:本文正在参与「掘金小册免费学啦!」活动, 点击查看活动详情