【3】图示:
文章插图
【4】图示参数说明
zlbytes:32bit , 表示ziplist占用的字节总数 。zltail:32bit , 表示ziplist表中最后一项(entry)在ziplist中的偏移字节数 。通过zltail我们可以很方便地找到最后一项 , 从而可以在ziplist尾端快速地执行push或pop操作zlen:16bit , 表示ziplist中数据项(entry)的个数 。entry:表示真正存放数据的数据项 , 长度不定zlend: ziplist最后1个字节 , 是一个结束标记 , 值固定等于255 。prerawlen: 前一个entry的数据长度 。len: entry中数据的长度data: 真实数据存储【5】说明
1.Ziplist的设计结构 , 保障了空间的节省与查询的高效 , 但是当出现zlentry增加或删除时 , Ziplist是不能直接在原有空间上进行修改 , 每一次变动都需要重新开辟空间去拷贝、修改 。这样的场景下Ziplist一旦内部元素过多 , 将会导致性能的急剧下滑 。因此Redis 在实现上做了一层优化 , 当Ziplist过大时 , 会将其分割成多个Ziplist , 然后再通过一个双向链表将其串联起来 。
3)quicklist 分析详解
【1】介绍
1.Redis quicklist是Redis 3.2版本以后针对链表和压缩列表进行改造的一种数据结构 , 是 zipList 和 linkedList 的混合体 , 相对于链表它压缩了内存 , 进一步的提高了效率 。
【2】代码展示
robj *createQuicklistObject(void) {quicklist *l = quicklistCreate();robj *o = createObject(OBJ_LIST,l);o->encoding = OBJ_ENCODING_QUICKLIST;return o;}//处于quicklist.c文件中quicklist *quicklistCreate(void) {struct quicklist *quicklist;quicklist = zmalloc(sizeof(*quicklist));quicklist->head = quicklist->tail = NULL;quicklist->len = 0;quicklist->count = 0;quicklist->compress = 0;quicklist->fill = -2;quicklist->bookmark_count = 0;return quicklist;}//处于quicklist.h文件中//quicklist 是一个 40 字节的结构(在 64 位系统上) , 描述了一个快速列表 。typedef struct quicklist {quicklistNode *head;//指向头节点(左侧第一个节点)的指针 。quicklistNode *tail;//指向尾节点(右侧第一个节点)的指针 。unsigned long count;// 所有 quicklistNode 节点中所有的 entry 个数unsigned long len;// quickListNode 节点个数 , 也就是 quickList 的长度int fill : QL_FILL_BITS;//单个节点的填充因子 , 也就是 ziplist 的大小unsigned int compress : QL_COMP_BITS;// 保存压缩成都只 , 配置文件设置 , 64位操作系统占 16bit , 6 表示压缩unsigned int bookmark_count: QL_BM_BITS;quicklistBookmark bookmarks[];} quicklist;//quicklistNode 是一个 32 字节的结构 , 描述了一个快速列表的 ziplist 。typedef struct quicklistNode {struct quicklistNode *prev;// 双向链表前驱节点struct quicklistNode *next;// 双向链表的后节点unsigned char *zl;//数据指针 。如果当前节点的数据没有压缩 , 那么它指向一个ziplist结构;否则 , 它指向一个quicklistLZF结构 。unsigned int sz;// 压缩列表 ziplist 的总长度unsigned int count : 16;// 每个 ziplist 中 entry 的个数unsigned int encoding : 2;// 表示是否采用了 LZF 压缩 quickList 节点 1 表示压缩过 , 2 表示没有压缩站 2bit 长度unsigned int container : 2;// 表示是否开启 ziplist 进行压缩unsigned int recompress : 1;// 表示该节点是否被压缩过unsigned int attempted_compress : 1;// 测试使用unsigned int extra : 10;// 额外拓展位 , 占 10bit 长度} quicklistNode;//当指定使用 lzf 压缩算法压缩 ziplist entry 节点时,quicklistNode 结构的 zl 成员执行 quicklistLZF 结构typedef struct quicklistLZF {unsigned int sz;//表示被LZF 压缩后的 ziplist 的大小char compressed[];// 压缩有的数据 , 柔性数组} quicklistLZF;
经验总结扩展阅读
- 七 Netty 学习:NioEventLoop 对应线程的创建和启动源码说明
- Spring mvc源码分析系列--Servlet的前世今生
- spring cron表达式源码分析
- 集合框架——LinkedList集合源码分析
- 含源码 手把手教你使用LabVIEW OpenCV DNN实现手写数字识别
- 补充部分---ScheduledThreadPoolExecutor类分析 线程池底层原理详解与源码分析
- 五 Netty 学习:服务端启动核心流程源码说明
- HashMap底层原理及jdk1.8源码解读
- 含源码 手把手教你使用LabVIEW人工智能视觉工具包快速实现传统Opencv算子的调用
- 含源码 手把手教你使用LabVIEW人工智能视觉工具包快速实现图像读取与采集