前言
Redis的压缩列表用到很多地方,比如List Hashp等,那么Redis的压缩列表到底是个啥子结构呢,本文来一起探讨
源文件代码:ziplist.c ziplist.h 在这两个文件中
数据结构
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
区域 | header | entries | end |
内存大小 | 4bytes | 4bytes | 2bytes | ? | ? | ? | 1bytes |
组件 | zlbytes | zltail | zllen | entry1 | entry2 | .......... | entryN | zlend |
地址 | | | |
ZIPLIST_ENTRY_HEAD | ZIPLIST_ENTRY_END
ZIPLIST_ENTRY_TAIL
源代码上也有这个的注解,大家可以看看,基本上是这个结构
各个域的左右如下
zlbytes: 内存字节数
zltail : zillist表尾的迁移
zllen : ziplist的节点数
entryN : 节点,实际存储数据的
zlend : ziplist的结束点
宏
ZIPLIST_ENTRY_HEAD : 到达压缩列表第一个节点
ZIPLIST_ENTRY_TAIL : 到达压缩列表最后一个节点
ZIPLIST_ENTRY_END : 到达ziplist的末端,理解长结束点
说完了ziplist的节点后,进入entryN 节点中,大家都知道压缩列表是为节约内存空间而设计的,其实在我看来是利用地址的连续,找到下一个节点,这里我介绍下entryN
entryN
area |<------------------- entry -------------------->| +------------------+----------+--------+---------+ component | pre_entry_length | encoding | length | content | +------------------+----------+--------+---------+
pre_entry_length: 上一个节点的长度
encoding: 00 01 10 代表content里面存储字符串数组,11代表content存储整形
length: 存储content长度
context: value值
总结: 对于压缩指针,其实在我看来是利用对内存的连续性,进行设计的列表,但是一个内容的长度,也会存储两次,这里也会浪费一点空间. 压缩列表每次的新增,删除,都会重新分配内存,这点的性能也不不是很友好,如果后期内存量大了,这就完蛋了。在redis4.0中,我看到了redis使用了快速列表,下一篇文章我将会对快速列表讲下。