第一部分 数据结构与对象
- Redis 是键值数据库。键通常是字符串对象,值有五种可能的对象:字符串,列表,哈希,集合,有序集合。第一部分是介绍这五种对象,剖析其底层数据结构,以及该数据结构对其功能和性能的影响
- Redis 是由 C 语言编写,所以出现的源码皆为 C 语言,其他语言会另外声明。
1. 简单动态字符串(simple dynamic string,SDS)
- Redis 中的 string 对象是根据 Redis 的功能专门设计的,没有直接使用 C 字符串。SDS 会被用作字符串对象的底层实现。SDS 定义如下。
-
这样设计有什么好处呢?
- 比 C 字符串更快获取长度
- C 字符串在拼接的时候可能出现缓冲区溢出的问题,而 SDS 结构的 API 会检查 free 字段的值,看是否需要扩展缓冲区。这就避免了缓冲区溢出问题
- Redis 作为数据库,在设计的时候,一定是假设数据会被经常访问和修改。那 C 字符串在 append 和 trim 的过程中会触发内存重分配。添加 length 和 free 字段可以有效减少内存重分配的压力。Redis 有一套机制。总的来说就是 append 的时候预留空间,trim 的时候不急着归还内存,以备不时之需。具体的数值自行查阅原文或其他相关资料。
- 在保存图像,音频等二进制数据的时候,C 字符串只能胜任保存文本数据,SDS 会以处理二进制的方式处理 buf 数组的数据。例如,SDS 使用 len 属性判断字符串是否结束,而不是空字符串。
- 此外 SDS 还被设计成兼容部分 C 字符串的函数,避免了重复造轮子。
2. 链表
- C 语言没有内置链表,Redis 在开发的过程中构建了自己的链表实现。此处的链表跟数据结构课上讲到的链表无太大区别。Node 定义如下。
- NodeList 定义如下。
- 相对应的,Redis 的设计者们给链表设计了丰富的 API。
- 链表在 Redis 中的实际应用:列表键,发布和订阅,慢查询,监视器等