WsztRush

Redis设计与实现

写在前面

这本书主要是讲Redis底层的实现,总体上分为四部分:

  1. 数据结构与对象
  2. 单机数据库的实现
  3. 多机数据库的实现
  4. 独立功能的实现

这个顺序和作者自己学习的顺序应该是一致的,但是感觉有一点不合理:在刚开始看的时候一直比较着急,因为是在对Redis整体上没有概念的情况下看细节。

学习笔记

在Redis中键为字符串、值为对象,底层处理用到的数据结构有:

  1. 动态字符串:使用预分配和惰性释放来减少内存操作次数
  2. 链表
  3. 字典:渐进式rehash防止卡住
  4. 跳跃表
  5. 整数集合:有序、不重复的整数集合,在必要的时候升级来节约内存
  6. 压缩列表:连续内存保存整数或字节的列表,通过压缩来节省内存
  7. 对象:在Redis中都是对象,实现基于上面的数据结构

由于Redis是用C编写的,没有垃圾回收机制,因此在对象系统中构建了一个引用计数实现内存回收器,通过该机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。

有了这些基础就可以开始看Redis作为一个服务器是如何工作的:

                  +-------------+                   
                  | redisServer |                   
                  +------+------+                   
                         |                          
+-----------+     +------+------+      +-----------+
|redisClient+-----+   redisDb   +--+---+    dict   |
+-----------+     +-------------+  |   +-----------+
                  |   redisDb   |  |                
                  +-------------+  |   +-----------+
                  |   redisDb   |  +---+  expires  |
                  +-------------+      +-----------+

其中:

  1. dict:键空间
  2. expires:键的过期时间

还有另外一种做过期时间的方法是:对dict上的键做扩展,增加过期时间字段。和Redis的做法相比可能有几个缺点:浪费空间、遍历时浪费时间、结构不清晰。过期键的删除有三种策略:

  1. 定时删除:在设置键的过期时间时创建Timer,当Timer运行时执行删除操作
  2. 惰性删除:在取值时判断是否过期,如果过期则删除
  3. 定期删除:每隔一段时间对数据库进行检查扫描,删除里面过期的键

定时删除显然不靠谱,在Redis中同时使用了定期删除惰性删除,当然在持久化程序中也需要考虑过期时间。