quickList介绍
在redis3.0以前,List对象的底层数据结构是双向链表或者压缩链表在3.2的时候,List对象的底层改为由quicklist数据结构实现。
quickList链表就是双向链表+压缩链表组合,quicklist本身是个链表,链表中的元素是压缩列表。
quicklist的数据结构
typedef struct quicklist {
//quicklist的链表头
quicklistNode *head;
//quicklist的链表尾
quicklistNode *tail;
//所有压缩列表中的总元素个数
unsigned long count;
//链表节点的个数 quicklistNode
unsigned long len;
...
} quicklist;
quicklistNode的结构定义
typedef struct quicklistNode {
//指向前节点的指针
struct quicklistNode *prev; //前一个quicklistNode
//指向后节点的指针
struct quicklistNode *next; //后一个quicklistNode
//quicklistNode指向的压缩列表
unsigned char *zl;
//压缩列表的的字节大小
unsigned int sz;
//压缩列表的元素个数
unsigned int count : 16; //ziplist中的元素个数
....
} quicklistNode;
可以看到 node节点有指向前节点和后节点的指针,以及节点的元素保存的不是单纯的元素值,而是保存了一个压缩链表,所以有个指向压缩链表的指针*zl
数据结构图
在向quicklist添加一个元素的时候,不会像普通的链表那样,直接新建一个链表节点。而是会检查插入位置的压缩链表是否能容纳该元素,如果能够容纳,那么就直接保存到quicklistNode结构里面的压缩列表,如果不能容纳,才会新建一个Node结构。
quicklist会控制quicklistNode结构里面的压缩列表的大小或者元素个数,用来规避潜在的连锁更新的风险,但是并没有完全解除。