目录
- 一、概述
- 二、ziplist结构
- 三、Entry结构
- 四、为什么ZipList特别省内存
- 五、ziplist的缺点
上一篇 redis底层数据结构之SDS
下一篇 明天更新
一、概述
一种连续内存空间存储的顺序数据结构,每个元素可以是字符串或整数。优点:节省内存空间。适用于存储小规模的列表或有序集合。缺点:修改操作可能引发连锁更新,影响性能。使用场景: 在列表键元素较少或元素都是小整数时使用。
二、ziplist结构
- Header(头部): 包含了ziplist的总字节长度、尾部(最后一个元素)的偏移量,以及ziplist中元素的数量。这些信息有助于快速地访问ziplist的基本属性和迅速找到ziplist的尾部。
- Entry(项): 每个项可以存储一个整数或者一个字符串。
- End(结束符): 一个特定的字节(通常是
0xFF
),标记着ziplist的末尾,确保了ziplist结构的正确解析和遍历的终止。
三、Entry结构
- Previous Entry Length(前一项的长度): 存储前一项的长度,使得ziplist可以被双向遍历。
- Encoding(编码): 指定了存储的值是整数还是字符串,以及使用了哪一种格式或长度。
- Content(内容): 实际存储的数据,可以是一个整数的二进制表示,或者是一个字符串的字节序列。
四、为什么ZipList特别省内存
- ziplist节省内存是相对于普通的list来说的,如果是普通的数组,那么它每个元素占用的内存是一样的且取决于最大的那个元素(很明显它是需要预留空间的);
- 所以ziplist在设计时就很容易想到要尽量让每个元素按照实际的内容大小存储,所以增加encoding字段,针对不同的encoding来细化存储大小;
- 这时候还需要解决的一个问题是遍历元素时如何定位下一个元素呢?在普通数组中每个元素定长,所以不需要考虑这个问题;但是ziplist中每个data占据的内存不一样,所以为了解决遍历,需要增加记录上一个元素的length,所以增加了prelen字段
五、ziplist的缺点
-
不预留内存空间:ziplist 不预留额外的内存空间,在写操作时可能需要频繁进行内存分配和释放操作,影响性能。
-
立即缩容:在移除节点后,ziplist 立即缩容,可能导致频繁的内存分配和释放操作。
-
链式扩容:节点如果扩容,可能导致节点占用的内存增长,并且在超过一定字节后,可能会导致链式扩容。链式扩容的时间复杂度为 O(N),虽然在大多数情况下概率较小,但在恶劣情况下会导致性能下降。
综上所述,尽管 ziplist 能够有效地节省内存空间,但在写操作频繁、节点删除较多或节点扩容较大时,可能会出现性能问题。