看了黄建宏老师的《Redis设计与实现》,对redis的部分实现有了一个简明的认识;

之前面试的时候被问到了这部分的内容,没有关注,好在还有时间,就把Redis的源码看了一遍。

Redis源码的获取

Redis是完全开源的,其源代码可以在直接在GitHub上获取:https://github.com/antirez/redis(目前的版本是4.4.0)。此时,进入解压后的redis目录下的src文件夹,redis的所有源代码都存放在此。

源代码结构解析

redis源码解析看到的redis源码阅读方法,我觉得这适用于很多源码的阅读:

  1. 自底向上:从耦合关系最小的模块开始读,然后逐渐过度到关系紧密的模块。就好像写程序的测试一样,先从单元测试开始,然后才到功能测试。
  2. 从功能入手:通过文件名(模块名)和函数名,快速定位到一个功能的具体实现,然后追踪整个实现的运作流程,从而了解该功能的实现方式。
  3. 自顶向下:从程序的 main() 函数,或者某个特别大的调用者函数为入口,以深度优先或者广度优先的方式阅读它的源码。
  • Redis的数据结构部分
内存分配 zmalloc.c和zmalloc.h
动态字符串 sds.h和sds.c
双端链表 adlist.c和adlist.h
字典 dict.h和dict.c
跳跃表 server.h文件里面关于zskiplist结构和zskiplistNode结构,以及t_zset.c中所有zsl开头的函数
  • Redis的内存编码
整数集合 intset.h和intset.c
压缩列表 ziplist.h和ziplist.c
压缩表 zipmap.h和zipmap.c
  • Redis数据类型
对象 object.c
字符串对象 t_string.c
列表对象 t_list.c
散列对象 t_hash.c
集合对象 t_set.c
有序集合对象 t_zset.c中除 zsl 开头的函数之外的所有函数
  • Redis数据库的实现
数据库实现 db.c
RDB持久化 rdb.c
AOF持久化 aof.c
通知功能 notify.c
  • 客户端和服务器端的代码实现
服务器端 redis.c
客户端 redis-cli.c
事件处理 ae.c/ae_epoll.c/ae_evport.c/ae_kqueue.c/ae_select.c
网络链接 anet.c和networking.c
  • Redis多机部分的代码实现
复制功能 replication.c
Redis Sentinel sentinel.c
集群 cluster.c
  • 独立功能模块的实现
发布和订阅 pubsub.c文件
事务 multi.c
lua脚本 scripting.c
慢查询 slowlog.c
监视 monitor.c

整个Redis的源码分类大体上如上所述了。

后面参考了知乎作者Zeech的关于redis阅读的建议:

Redis

redis全称REmote DIctionary Server,是一个由Salvatore Sanfilippo写的高性能key-value存储系统,其完全开源免费,遵守BSD协议。Redis与其他key-value缓存产品(如memcache)有以下几个特点。

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

Redis的性能极高且拥有丰富的数据类型,同时,Redis所有操作都是原子性的,也支持对几个操作合并后原子性的执行。另外,Redis有丰富的扩展特性,它支持publish/subscribe, 通知,key 过期等等特性。

这里贴出针对Zeech提供的阅读建议,也可以督促自己,希望能够对找到工作有所帮助。

第一阶段

  • 阅读Redis的数据结构部分,基本位于如下文件中:内存分配 zmalloc.c和zmalloc.h
  • 动态字符串 sds.h和sds.c
  • 双端链表 adlist.c和adlist.h
  • 字典 dict.h和dict.c
  • 跳跃表 server.h文件里面关于zskiplist结构和zskiplistNode结构,以及t_zset.c中所有zsl开头的函数,比如 zslCreate、zslInsert、zslDeleteNode等等。
  • 基数统计 hyperloglog.c 中的 hllhdr 结构, 以及所有以 hll 开头的函数

第二阶段 熟悉Redis的内存编码结构

  • 整数集合数据结构 intset.h和intset.c
  • 压缩列表数据结构 ziplist.h和ziplist.c

第三阶段 熟悉Redis数据类型的实现

  • 对象系统 object.c
  • 字符串键 t_string.c
  • 列表建 t_list.c
  • 散列键 t_hash.c
  • 集合键 t_set.c
  • 有序集合键 t_zset.c中除 zsl 开头的函数之外的所有函数
  • HyperLogLog键 hyperloglog.c中所有以pf开头的函数

第四阶段 熟悉Redis数据库的实现

  • 数据库实现 redis.h文件中的redisDb结构,以及db.c文件
  • 通知功能 notify.c
  • RDB持久化 rdb.c
  • AOF持久化 aof.c

以及一些独立功能模块的实现

  • 发布和订阅 redis.h文件的pubsubPattern结构,以及pubsub.c文件
  • 事务 redis.h文件的multiState结构以及multiCmd结构,multi.c文件

第五阶段 熟悉客户端和服务器端的代码实现

  • 事件处理模块 ae.c/ae_epoll.c/ae_evport.c/ae_kqueue.c/ae_select.c
  • 网路链接库 anet.c和networking.c
  • 服务器端 redis.c
  • 客户端 redis-cli.c
  • 这个时候可以阅读下面的独立功能模块的代码实现
  • lua脚本 scripting.c
  • 慢查询 slowlog.c
  • 监视 monitor.c

第六阶段 这一阶段主要是熟悉Redis多机部分的代码实现

  • 复制功能 replication.c
  • Redis Sentinel sentinel.c
  • 集群 cluster.c

其他代码文件介绍

关于测试方面的文件有:

  • memtest.c 内存检测
  • redis_benchmark.c 用于redis性能测试的实现。
  • redis_check_aof.c 用于更新日志检查的实现。
  • redis_check_dump.c 用于本地数据库检查的实现。
  • testhelp.c 一个C风格的小型测试框架。

一些工具类的文件如下:

  • bitops.c GETBIT、SETBIT 等二进制位操作命令的实现
  • debug.c 用于调试时使用
  • endianconv.c 高低位转换,不同系统,高低位顺序不同
  • help.h 辅助于命令的提示信息
  • lzf_c.c 压缩算法系列
  • lzf_d.c 压缩算法系列
  • rand.c 用于产生随机数
  • release.c 用于发布时使用
  • sha1.c sha加密算法的实现
  • util.c 通用工具方法
  • crc64.c 循环冗余校验
  • sort.c SORT命令的实现
  • 一些封装类的代码实现:
  • bio.c background I/O的意思,开启后台线程用的
  • latency.c 延迟类
  • migrate.c 命令迁移类,包括命令的还原迁移等
  • pqsort.c 排序算法类
  • rio.c redis定义的一个I/O类
  • syncio.c 用于同步Socket和文件I/O操作

redis源代码结构解析的更多相关文章

  1. Redis源码剖析--源码结构解析

    请持续关注我的个人博客:https://zcheng.ren 找工作那会儿,看了黄建宏老师的<Redis设计与实现>,对redis的部分实现有了一个简明的认识.在面试过程中,redis确实 ...

  2. Redis源代码分析(一)--Redis结构解析

    从今天起,本人将会展开对Redis源代码的学习,Redis的代码规模比較小,很适合学习,是一份很不错的学习资料,数了一下大概100个文件左右的样子,用的是C语言写的.希望终于能把他啃完吧,C语言好久不 ...

  3. Redis源代码解析:13Redis中的事件驱动机制

    Redis中.处理网络IO时,採用的是事件驱动机制.但它没有使用libevent或者libev这种库,而是自己实现了一个很easy明了的事件驱动库ae_event,主要代码只400行左右. 没有选择l ...

  4. 【Redis源代码剖析】 - Redis内置数据结构之压缩字典zipmap

    原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/article/details/51111230 今天为大家带来Redis中zipmap数据结构的分析,该结构定义在 ...

  5. 升讯威微信营销系统开发实践:(4)源代码结构说明 与 安装部署说明( 完整开源于 Github)

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  6. redis 源代码分析(一) 内存管理

    一,redis内存管理介绍 redis是一个基于内存的key-value的数据库,其内存管理是很重要的,为了屏蔽不同平台之间的差异,以及统计内存占用量等,redis对内存分配函数进行了一层封装,程序中 ...

  7. Redis源代码分析(十一年)--- memtest内存测试

    今天,我们继续redis源代码test下测试在封装中的其它文件.今天读数memtest档,翻译了,那是,memory test 存储器测试工具..可是里面的提及了非常多东西,也给我涨了非常多见识,网上 ...

  8. Android相框 与 源代码结构

    一. Android 相框 Android框架层级 : Android 自下 而 上 分为 4层; -- Linux内核层; -- 各种库 和 Android执行环境层; -- 应用框架层; -- 应 ...

  9. Couchbase集群和Redis集群解析

    Couchbase集群和Redis集群解析 首先,关于一些数据库或者是缓存的集群有两种结构,一种是Cluster;一种是master-salve. 关于缓存系统一般使用的就是Redis,Redis是开 ...

随机推荐

  1. StreamWrite类

    FileStream类,该对象只能以字节形式读取/写入数据,这就使得操作非常困难. 一般有了FileStream对象,都会借用StreamWrite对象或StreamReader对象的方法来处理文件. ...

  2. 一个WPF小项目小结

    一:缘起 老板有做PC桌面客户端的需求,做的是能耗的计算和评估,要算能耗,就有很多环节,最后对这些环节数据进行一些简单计算.我想要是做的话就用比较熟的wpf,就去聊了下,对方给了1张比较复杂的Exce ...

  3. JavaScript 对象继承 OOP (三)

      对象继承 A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. JavaScript 语言的继承不通过 class (es6 中的class 不过是 ...

  4. node.js 模块和其下载资源的镜像设置

    以前安装 electron 时总是失败,然后就在淘宝镜像上下载好相应版本的文件放到用户目录来解决问题. 后来研究发现 npm 不仅可以设置 node.js 模块仓库的代理, 同样可以设置像 elect ...

  5. php支付走过的坑(支付宝篇 注册 秘钥 环境等等配置)

    支付这东西,说容易也容易,说难也难 代码这玩意还比较好说 但是 如果没有demo 直接去看官方文档 十有八九一脸懵逼 今天就整理一下 支付这块走过的坑 涉及 微信h5支付 支付宝h5支付 (api文档 ...

  6. Conferences

    中国学术会议在线 :http://www.meeting.edu.cn 中国会议网: http://www.chinameeting.com 香山科学会议:http://www.xssc.ac.cn/ ...

  7. [SVN]TortoiseSVN工具培训3─使用基本流程和图标说明

    1.SVN的使用基本流程 注意:对于文件编辑方面,上图的编辑副本操作前建议进行Get lock操作,以防出现后续的冲突等异常报错. 2.SVN的基本图标说明

  8. 在IE中解决当前安全设置不允许下载该文件的方案

    解决方案一: 1.0打开IE后,单击菜单栏中的“工具”菜单,在弹出的菜单中选择“Internet选项”命令: 2.0在弹出“Internet选项”的对话框中,打开“Internet选项”对话框: 3. ...

  9. MySQL入门很简单: 14MySQL日志

    二进制日志: 以二进制文件的形式记录了数据库中的操作,但不记录查询语句 错误日志: 记录MySQL服务器的启动,关闭和运行错误等信息 通用查询日志: 记录用户登录和记录查询的信息 慢查询日志: 记录执 ...

  10. *459. Repeated Substring Pattern (O(n^2)) two pointers could be better?

    Given a non-empty string check if it can be constructed by taking a substring of it and appending mu ...