redis源码解析¶
Warning
本文档主要是redis源码的解析, 在阅读本文档前最好先阅读 redis的设计与实现 。 源码的阅读主要是学习作者的代码风格、 编程技巧、 以及系统原理。 本文档主要就是介绍上面相关的三点, 源码是基于redis3.0。
Note
源码阅读方法:
- 自底向上:从耦合关系最小的模块开始读,然后逐渐过度到关系紧密的模块。就好像写程序的测试一样,先从单元测试开始,然后才到功能测试。我在刚开始读 Redis 源码的时候,使用的就是这种方法:先从单独的数据结构模块开始,然后再过渡到高层的功能模块。
- 从功能入手:通过文件名(模块名)和函数名,快速定位到一个功能的具体实现,然后追踪整个实现的运作流程,从而了解该功能的实现方式。我在读阻塞列表、数据库这种流程和功能都比较复杂,和其他文件耦合也比较多的模块时,使用的就是这样的方法。
- 自顶向下:从程序的 main() 函数,或者某个特别大的调用者函数为入口,以深度优先或者广度优先的方式阅读它的源码。我在阅读 redis.c/serverCron() 、 redis.c/main() 和 ae.c/aeMain() 这种有明显调用者性质的函数时,使用的就是这样的方法。
第一部分 内部数据结构¶
作者为了系统的性能, 实现了很多数据结构, 如sds、adlist、dict和skiplist。
第二部分 内存压缩结构¶
redis 还使用了一些特殊的存储结构, 在条件容许的情况下, 会使用压缩数据结构替代内部数据结构。 创建它们所消耗的内存通常比作用类似的内部数据结构要少得多, 如果使用得当, 压缩数据结构可以为用户节省大量的内存。 压缩数据结构的编码和操作方式要比内部数据结构要复杂得多, 所以所占用的 CPU 时间会比作用类似的内部数据结构要多。
第三部分 内存存储结构¶
Redis 是支持多key-value数据库(表)的,并用 RedisDb 来表示一个key-value数据库(表). redisServer 中有一个 redisDb *db成员变量, RedisServer 在初始化时,会根据配置文件的 db 数量来创建一个 redisDb 数组. 客户端在连接后,通过 SELECT 指令来选择一个 reidsDb,如果不指定,则缺省是redisDb数组的第1个(即下标是 0 ) redisDb. 一个客户端在选择 redisDb 后,其后续操作都是在此 redisDb 上进行的. 下面会详细介绍一下 redisDb 的内存结构.
第四部分 初始化¶
主要介绍redis.h/redis.c/redis-cli.c的内容,主要介绍介绍一些初始化过程,详细的应该在服务器调优的时候才可以体会。