Redis 已是你们耳熟能详的东西了,平常工做也都在使用,面试中也是高频的会涉及到,那么咱们对它究竟了解有多深入呢?面试
我读了几本 Redis 相关的书籍,尝试去了解它的具体实现,将一些底层的数据结构及实现原理记录下来。后端
本文将介绍 Redis 中底层的 listpack(紧凑列表) 的实现方法。 它是 Redis 的 Stream 用到的数据结构之一。数组
Redis 设计 listpack 的目的就是取代 ziplist, 在 Redis 系列(三)底层数据结构之压缩列表 中咱们提到,ziplist 在极小的几率下有可能发生级联更新,当连续规模较大的级联更新发生时,对 Redis 的性能有比较大的影响。微信
虽然咱们都知道这是极小的几率,可是这种设计缺陷却不能被 Redis 的大佬做者所接受,所以在 5.0 版本中新引入了一个数据结构,名叫 listpack, 你们都将它翻译为 紧凑列表.markdown
它的定义和 ziplist 极其类似,只是经过一些新的设计,来解决 ziplist 中的痛点问题。所以本文的讲解基于读者已经了解 ziplist.数据结构
ziplist的定义以下: 注意:这是 ziplist 的定义oop
struct ziplist<T>{ // 整个压缩列表占用字节数 int32 zlbytes; // 最后一个节点到压缩列表起始位置的偏移量,能够用来快速的定位到压缩列表中的最后一个元素 int32 zltail_offset; // 压缩列表包含的元素个数 int16 zllength; // 元素内容列表,用数组存储,内存上紧挨着 T[] entries; // 压缩列表的结束标志位,值永远为 0xFF. int8 zlend; } 复制代码
listpack 的定义和上方基本一致,只是去掉了 zltail_offset 属性。性能
让咱们回想一下,ziplist 中用这个属性作什么?用来方便的找到最后一个节点,而后方便进行反向的遍历。新的 listpack 固然是解决了这个问题,才能放心的删除掉这个属性。学习
listpack节点的定义以下:url
int<var> encoding; optional byte[] content; int<var> length; 复制代码
相比于 ziplist 的定义,它有两点改动:
这样作的好处是:
listpac 的总长度-最后一个节点的长度
.listpack 是 Redis 设计用来取代掉 ziplist 的数据结构,它经过每一个节点记录本身的长度,且放在节点的尾部,来完全解决掉了 ziplist 存在的级联更新的问题。
listpack 在 5.0 版本引入,可是因为 ziplist 在 Reids 内部的使用太过于普遍,有一些兼容问题,咱们能够预见这将是一个逐步的替换过程。
一样在 5.0 版本引入的 Stream 数据结构中,就使用了 listpack 而不是 ziplist.
《Redis 的设计与实现(第二版)》
《Redis 深度历险:核心原理和应用实践》
完。
最后,欢迎关注个人我的公众号【 呼延十 】,会不按期更新不少后端工程师的学习笔记。 也欢迎直接公众号私信或者邮箱联系我,必定知无不言,言无不尽。
以上皆为我的所思所得,若有错误欢迎评论区指正。
欢迎转载,烦请署名并保留原文连接。
联系邮箱:huyanshi2580@gmail.com
更多学习笔记见我的博客或关注微信公众号 < 呼延十 >------>呼延十