简介
降低 Redis 的内存占用有助于减少创建快照和加载快照所需的时间、提升载入 AOF 文件和重写 AOF 文件时的效率、缩短从服务器进行同步所需的时间(快照、 AOF 文件重写在 持久化选项 中进行了介绍,从服务器同步在 复制、处理故障、事务及性能优化 中进行了介绍),并且能让 Redis 存储更多的数据而无需添加额外的硬件。 P208
短结构 (short structure) P208
Redis 为列表、集合、散列和有序集合提供了一组配置选项,这些选项可以让 Redis 以更节约空间的方式存储长度较短的结构(后面简称“短结构”)。 P208
在列表、散列和有序集合的长度较短或者体积较小的时候, Redis 可以选择使用一种名为压缩列表 (ziplist) 的紧凑存储方式来存储这些机构。压缩列表是列表、散列和有序集合这 3 种不同类型的对象的一种非结构化 (unstructured) 表示:与 Redis 在通常情况下使用双向链表表示列表、使用散列表表示散列、使用散列表加上跳表 (skiplist) 表示有序集合的做法不同,压缩列表会以序列化的方式存储数据,这些序列化数据每次被读取的时候都要进行解码,每次被写入的时候也要进行局部的重新编码,并且可能需要对内存里面的数据进行移动。 P209
压缩列表表示 P209
本节以最简单的列表进行观察对比。
双向链表 P209
列表不进行压缩时使用双向链表 (doubly linked list) 进行存储,链表的每个结点都有三个指针: P209
- 指向前一个结点的指针
- 指向后一个结点的指针
- 指向结点包含的字符串值的指针
其中字符串值又分为三个部分: P209
- 字符串的长度
- 字符串剩余可用的字节数
- 以空字符结尾的字符串本身
可以发现未压缩前,每存储一个字符串,最少需要 21 字节的额外开销 (overhead) 。(三个指针每个占 4 个字节,两个整数每个占 4 个字节,字符串结尾的空字符占 1 个字节) P209
压缩列表 P209
压缩列表是由结点(非真实结点)组成的序列 (sequence) ,每个结点都由两个长度值和一个字符串组成。 P209
- 第一个长度值:前一个结点的长度,用于从后向前的遍历(一般以一个字节存储)
- 第二个长度值:当前结点的长度(一般以一个字节存储)
- 字符串:长度等于字节数,没有空字符
可以发现压缩后,每存储一个字符串,最少需要 2 字节的额外开销。