从今天开始阅读《Redis设计与实现》黄建宏写的这本书,这本书详细的解释了Redis设计思想与代码实现,解释的很细节,容易理解。
以后会连载Redis设计与实现系列的阅读笔记,记录自己的理解,有问题大家提出来一起学习进步。
Redis数据结构包含:简单动态字符串(SDS)、链表、字典、跳跃表、整数集合、压缩列表六种。
下面一一进行解释。
一、简单动态字符串
每个sds.h/sdshdr结构表示一个SDS值:
struct sdshdr {
int len; //记录buf中已经使用字节的数量,等于SDS中所保存字符串的长度
int free; //记录buf中未使用字节的数量
char buf[]; //自己数组,用于保存字符串 按照字节形式保存,可以兼容任何格式的字符串
}
SDS与C字符串的区别:
1.常数复杂度获取字符串长度
2.杜绝缓冲区溢出
3.减少修改字符串时带来的内存充分配次数
4.二进制安全(Redis不仅可以保存文本数据,而且可以保存任意格式的二进制数据)
5.兼容部分C字符串函数
通过未使用空间(free值对应的buf空间),SDS实现了空间预分配和惰性空间释放两种优化策略
空间预分配
额外分配的未使用空间数量由以下公式决定:
a)如果对SDS修改后,SDS的长度(len值)小于1MB,那么程序分配和len属性相同大小的未使用空间(这时len和free值将相等);
b)如果对SDS修改后,SDS长度大于等于1MB,那么程序分配1MB的未使用空间。
惰性空间释放
通过惰性空间释放策略,SDS避免了缩短字符串时所需的内存重分配操作,并为将来可能有的增长操作提供了优化。