Redis数据结构详解(4)-为了节约内存的数据结构(压缩列表ziplist)
前提知识
前面几个文章里我们介绍到了字典dict和跳表skiplist,它们都是redis为了追求性能而开发的基本数据结构,里面或多或少都借助了一些辅助的元素;例如字典dict在rehash时会同时存在两个哈希表,又或者跳表skiplist里节点多了层的结构,这些设计都是为了追求性能而牺牲了内存空间。
【Redis数据结构详解(4)-为了节约内存的数据结构(压缩列表ziplist)】如果你多多少少了解HashMap的底层原理的话,你就知道:
在JDK1.8中,随着元素越来越多,HashMap发生hash冲突,桶中元素大于等于8个,并且容量大于等于64时,会由链表形式转化为红黑树结构;而当桶中元素降到6时又会转换回链表。
为什么有这样的变化呢?因为这体现了时间和空间平衡的思想,元素刚开始并不多时,链表的空间占用是比较少的,并且由于链表短,查询需要的时间也没有太大问题;可是随着链表越来越长,查询的需要的时间也就越来越长,就需要用占用空间大但是查询更高效的红黑树来帮忙了。
时间or空间,看来所有的数据结构都离不开这个命题。
而我们今天要说的压缩列表ziplist就是redis为了节约内存而设计开发的数据结构,并且作为列表键和哈希键的底层实现之一。
压缩列表ziplist的“登场时机”
- hash(下面条件满足其一,hash会由压缩列表ziplist结构转成字典dict结构)
- 键值对数目超过512。
- 插入一个value长度超过64的键值对。
- sorted set(下面条件满足其一,sorted set会由压缩列表ziplist结构转成zset结构——包含一个dict和一个skiplist)
- 键值对数目超过128。
- 插入一个value长度超过64的键值对。
压缩列表的结构
![Redis数据结构详解(4)-为了节约内存的数据结构(压缩列表ziplist)](https://cdn.nlark.com/yuque/0/2022/png/26199710/1649229949769-e6d367fc-bfac-4573-933f-5aba71db312e.png#clientId=u9b40493d-6782-4&crop=0&crop=0&crop=1&crop=1&from=paste&<br />
文章图片 <br />
<br>各个部分在内存是连续的,对应的含义如下:<br />
<ul>
<li><zlbytes>:4字节;用来记录整个压缩列表占用的内存字节数。</li>
<li><zltail>:4字节,用来记录压缩列表表尾节点(最后一个entry)距起始地址有多少字节,即偏移字节数。</li>
<li><zllen>:2字节,记录了包含的节点数量,即entry的个数。当entry个数小于2^16-1(65535)时,这个属性值就是压缩列表包含的节点个数;而当这个值等于2^16-1时(该字段只有2字节,16bit,即能表示的最大值,所有位数都为1),节点数量需要遍历整个压缩列表才能得出。</li>
<li><entry>:长度不定,用来存放实际要存储的数据项,有对应的结构,下面会再介绍。</li>
<li><zlend>:1字节,固定为255,用来标记压缩列表的末端。</li>
</ul>
<img alt=)
推荐阅读
- 算法与数据结构|第十届蓝桥杯大赛软件类省赛Java研究生组-题解
- python进阶之魔术方法详解
- 鸿蒙OS如何开发一个前端应用详解
- java中String|java中String StringBuffer和StringBuilder的区别详解
- 网络协议之:socket协议详解之Unix|网络协议之:socket协议详解之Unix domain Socket
- 详解Java中的mapstruct插件使用
- vue拖拽组件vuedraggable使用说明详解
- 委托代码详解
- docker方式实现redis数据持久化离线安装
- C语言下快速排序(挖坑法)详解