Redis 源码剖析与实战
蒋德钧
中科院计算所副研究员
17747 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
Redis 源码剖析与实战
15
15
1.0x
00:00/16:45
登录|注册

开篇词 | 阅读Redis源码能给你带来什么?

讲述:蒋德钧大小:15.31M时长:16:45
你好,我是蒋德钧,目前在中科院计算所任职副研究员。在 2015 年的时候,我和团队开始设计实现一个高性能键值数据库。为了实现这一目标,我们调研了业界常用的多种键值数据库,并选择 Redis 作为重点研究对象。在学习 Redis 的过程中,我就通读了 Redis 的源码,尤其是 Redis 的数据结构、主从复制、RDB/AOF 等关键功能。
也正是通过阅读 Redis 源码,我发现自己对 Redis 的关键设计原理和机制,有了更加直接和深刻的理解。更重要的是,Redis 的代码设计和实现教给了我很多计算机系统的设计思路,让我受益匪浅。
2020 年,我在极客时间上开设了一门《Redis 核心技术与实战》课程,来帮助同学们掌握 Redis 的核心原理和实战应用技术。在课程的更新和学习过程中,也有不少同学说想要了解和学习 Redis 源码,但是又苦于无从下手。因此时隔一年,我又带来了一个源码课程。
这门课程会从 Redis 源码阅读的角度出发,一方面会给你介绍 Redis 关键技术的代码实现,以便你能更加彻底地理解和掌握该项关键技术。另外更重要的一方面就是,我希望通过这门课程,把我当时在阅读 Redis 源码时,体会和掌握到的计算机单机系统和分布式系统常见的设计思想,分享给你,让你也可以把这些设计思想应用到自身的项目开发中。
好了,那么接下来,我就先和你聊聊阅读 Redis 源码能给我们带来什么,也就是为什么要学习 Redis 源码。

会用 Redis 不就行了,为啥要读源码呢?

平常我们在基于 Redis 做应用开发时,可能只是将 Redis 作为一个缓存系统或是数据库来存取数据,并不会接触到源码层面的东西。比如,我们在做社交应用开发时,会将用户数据、关注信息等缓存在 Redis 中;在开发存储系统软件时,也会用 Redis 保存系统元数据。
不过,我遇到过不少做开发或是运维的团队,他们在使用或运维 Redis 时,经常会面临 Redis 性能变差、Redis 实例故障等问题,而这些问题都会影响到业务应用的运行。再者,经历过大厂面试的人也知道,很多互联网公司在招聘资深技术岗时,都会问一些跟 Redis 相关的考点问题。
也就是说,如果你不了解 Redis 源码层面的实现原理,那不管你是在实际开发中排查问题故障点,还是在技术面试中快速拆解问题的套路,都可能会受到阻碍。
我就举个简单的例子。Redis 在运行过程中,随着保存数据的增加,会进行 rehash 操作,而 rehash 操作会对 Redis 的性能造成一定影响。如果我们想定位当前性能问题是否由 rehash 引起,我们就需要了解 rehash 的具体触发时机,这就包括 rehash 的触发条件有哪些,以及在哪些操作过程中会对这些触发条件进行判断。
可是,当我们只是了解 rehash 的基本原理时,我们就只是知道当哈希表的负载因子大于预设阈值后,就会开始执行 rehash。但是,具体到 Redis 来说,我们还需要进一步了解:
哈希表的负载因子是怎么算的?知道了这一点,我们可以推算 Redis 的负载压力。
除了负载因子这一条件,是否还有其他触发条件?了解这一点,可以帮助我们结合 Redis 运行情况,推断当前是否发生 rehash。
rehash 触发条件的判断会在哪些函数中进行调用?了解这一点很有用,可以让我们知道在哪些操作执行过程中,会判断 rehash 触发条件,进而执行 rehash。
你看,虽然从原理上说这是一个 rehash 操作,但一旦落到实际的性能问题排查时,我们却会面临很多的具体问题。
那么,要想解答这些问题,最好的办法就是阅读和学习 Redis 源码。通过学习源码,我们能进一步掌握 Redis 的实现细节,这带来的最明显收益就是,能了解 Redis 运行过程中要判断和处理的各种条件。这些细节正对应了我们在排查 Redis 性能、故障问题时的排查思路,可以帮助我们有章法、高效地解决问题。
另外,从我的经验来看,学习源码除了能帮助我们掌握 Redis 的设计细节,还能带来以下三点收获。
第一,从原理到源码,学习源码阅读方法,培养源码习惯,掌握学习主动权。
阅读源码本身是一个辛苦的过程,尤其是面对像 Redis 这样的系统软件。但是,你一旦掌握了阅读方法,进而养成了阅读习惯后,你就能从源码中掌握 Redis 的各种实现细节,建立对 Redis 的全面认识。这样一来,你就能成为一名 Redis 专家。
除此之外,一旦我们养成阅读源码的习惯,再遇到问题时,我们就会“条件反射”式地从源码中去寻找答案。而且,Redis 的代码一直在不断迭代更新,因此更新代码所对应的工作原理有时也会发生一些变化,但是又没有材料可以及时介绍代码更新带来的变化。此时,如果我们已经习惯从代码层去理解 Redis 的工作机制的话,那么,我们就能在第一时间掌握 Redis 的新发展和新变化,并可以将其应用到实际工作中。
比如,Redis 在 2020 年 5 月份推出了 6.0 版本,在该版本中,Redis 实现了多 IO 线程机制。如果我们养成了阅读 Redis 源码的习惯,就可以尽早地了解 Redis 6.0 中多 IO 线程的具体实现,并评估其可用性。
第二,学习良好的编程规范和技巧,写出高质量的代码。
学习 Redis 源码给我们带来的第二个收获,是它提供了一个经典的、使用 C 语言开发的软件系统示例,可以让我们学习掌握良好的 C 语言编码规范和技巧。
Redis 的稳定版包括 2、3、4、5,以及 2020 年发布的 6.0 版本,这些版本在实际业务中都有部署使用,其代码稳定性和健壮性也都经过了考验。因此,Redis 的源码是一份优秀的 C 语言编程学习素材。无论你是 C 语言的初学者,还是有经验的 C 语言开发者,通过学习 Redis 源码,都可以帮助你掌握编码规范和技巧。
比如,我们可以从 Redis 源码中学习功能模块单元测试的编程方法,下面的代码就显示了 Redis SDS 数据类型的单元测试,通过定义测试函数,以及宏定义开关,就可以实现针对 SDS 类型的各种操作测试。
int sdsTest() {
...
}
#ifdef SDS_TEST_MAIN
int main(void) {
return sdsTest();
}
#endif
第三,举一反三,学习计算机系统设计思想,实现职业能力进阶。
最后,学习 Redis 源码还有一个大收获,就是跟着 Redis 学习计算机系统的关键设计思想。Redis 是一个非常经典的内存数据库,它的设计与实现涉及两类计算机系统的关键技术。
一是单机键值数据库的关键技术,包括支持高性能访问的数据结构、支持高效空间利用率的数据结构、网络服务器高并发通信、高效线程执行模型、内存管理、日志机制等。这些技术是设计和实现一个单机键值数据库时都需要考虑的问题。
二是分布式系统的关键技术,包括分布式系统主从库复制机制、可扩展集群数据切片与放置技术、可扩展集群通信机制等。
Redis 在开发时,就针对上述问题进行了合理的设计和优化。因此,你通过阅读 Redis 源码,就可以充分学习到这些计算机系统的设计思想,并把它们应用到自身的项目开发中,这样进一步也能提升你的职业竞争力。
我画了下面这张图,显示了通过阅读 Redis 源码,可以学习和掌握到的计算机系统设计思想,你可以看下。
好了,到这里,你就可以发现,阅读和学习 Redis 源码,无论是对掌握 Redis 细节,成为 Redis 达人,还是养成源码阅读习惯,主动跟进 Redis 最新发展,或者是跟着 Redis 学习编程规范和设计思想,都大有裨益。

如何正确学习 Redis 源码?

但是,你在尝试阅读 Redis 源码的时候,有没有感到无从下手或是无所适从,比如说:
Redis 源码中的功能模块很多,不清楚它们之间的逻辑关系,或是某个模块中的内容很多,很难厘清一条清晰的调用路径;
花费了很多时间阅读代码,但总是抓不住重点,或者是在阅读一个函数代码时,很容易陷入细节之中,无法快速抓住代码的关键部分。
其实,你之所以“无从下手”的原因,是缺少了代码结构的全景图,而出现“无所适从”的问题,是缺少阅读目标的牵引和基本原理的支撑。简单来说,就是没有掌握科学、高效的代码阅读方法。
根据我阅读 Redis 这种大型系统源码的经验,下面我就来给你提供三个锦囊妙计。
高效阅读代码的第一个要点,是要先从整体上掌握源码的结构。
这是因为,如果一开始就盯着一个代码文件看,这样就很容易陷入到细节中,无法从全局上了解到 Redis 源码的组成,也不容易分清主次。
所以,对于阅读 Redis 源码来说,我们就需要先形成一幅 Redis 源码的全景图,如下所示。
有了这张图以后,我们就可以根据自己的学习需求,查找到所要学习的代码文件。然后,我们再根据 Redis 不同的功能特性,分线条学习每个功能特性上涉及的关键技术和设计思想。
高效阅读代码的第二个要点,是一定要有目标牵引和原理支撑。
Redis 的功能模块很多,每个功能模块的实现也比较复杂,我们在阅读代码前一定要明确想要了解的目标,比如是想了解某个数据结构,还是想要了解主从复制的流程。
在确定目标后,我们还需要对相应的原理有所了解,然后再开始阅读源码。这是因为源码是原理的体现,如果对 Redis 功能的基本原理不了解,直接阅读源码,就难于理解代码逻辑,增加了代码阅读的难度。
高效阅读代码的第三个要点,是要做到先主线逻辑再分支细节。
虽然说源码是原理的体现,但是和原理相比,源码通常会考虑系统运行时的各种情况和细节。我看到有些开发人员在阅读源码时,一上来就阅读代码中的每个分支,然后在每个分支上又追到每个函数中细看。而不同分支上的函数往往又涉及其他处理细节,这样一来,就会导致自己既不容易理解代码的主要逻辑,又会感到代码不好读,容易气馁。
其实,我们在阅读代码时一定要先把功能模块的主线逻辑梳理出来,具体来说,就是先把代码执行路径了解清楚,其中的分支做好标记,不用一开始就逐行阅读。等主线逻辑清楚后,我们再学习不同分支的处理。
比如,我们在阅读 Redis 事件驱动处理框架代码时,就需要在代码中先把事件处理流程的主要步骤梳理出来,包括创建事件、监听事件、启动事件处理循环。然后,我们再去了解事件创建、监听和处理的各种细节。这样一来,代码阅读就能更加高效了。
好了,在了解了代码学习方法之后,我们可以开始深入 Redis 具体的源码模块当中,去学习不同功能特性的设计与实现了。

这门课程是怎样设计的?

说到 Redis 的功能特性,Redis 提供了 String、List、Hash、Set、Sorted Set 等丰富的数据类型,同时,Redis 的访问性能高,还能构建成主从集群、切片集群来分别提升 Redis 使用的可靠性和可扩展性。
因此,针对 Redis 的上述功能特性,我把这门课程分成五大模块,具体如下。
数据结构:你将学习到 Redis 主要数据结构的设计思想和实现,包括字符串的实现方法、内存紧凑型结构的设计、哈希表性能优化设计,以及 ziplist、quicklist、listpack、跳表的设计与实现等。
网络通信与执行模型:你将掌握 Redis server 的启动流程、高性能网络通信设计与实现、事件驱动框架的设计与实现、Redis 线程类型的设计和优化等。
缓存:你将了解常见缓存替换算法如何从原理转变为代码。
可靠性保证:你将掌握 RDB、AOF 的具体实现,分布式系统中 Raft 一致性协议的设计实现,故障切换的关键代码实现等。
切片集群:你将学习到 Redis 切片集群中关键机制的设计与实现,包括 Gossip 通信协议、请求重定向、数据迁移等。
并且,在学习这五类模块中的关键源码的同时,我还会给你介绍对应的计算机系统设计思想,以便你把这些设计思想应用到自己的系统开发中。最后,我还会向你介绍 Redis 源码中使用的一些编程技巧,以便你学习掌握后,应用到自己的程序开发中。

写在最后

万事开头难,对于阅读源码来说,尤其是这样。Redis 有上百个源码文件,源码文件中的代码动辄上千行。如果想彻底掌握 Redis 源码,的确需要花大量的精力和时间。
但是,掌握一个好方法,是成功做好一件事的关键。所以,在跟随学习 Redis 源码的过程中,希望你能掌握好我给出的三个学习要点:
获得代码全景图;
在阅读代码前确定具体学习目标,并做好原理准备;
在阅读代码时,先梳理出代码的主线逻辑,再详细学习分支细节。
最后,我还想正式认识一下你。你可以在留言区做个自我介绍,和我聊聊你目前使用 Redis 或阅读 Redis 的源码时,都存在哪些困难,或是都有哪些独特的思考和体验,我们一起交流讨论。
好了,让我们一起努力,开始 Redis 代码之旅吧。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何正确学习Redis源码以及Redis源码阅读的方法和技巧。首先,通过深入阅读Redis源码,可以更全面地理解Redis的关键设计原理和机制,从而解决实际应用中的性能和故障问题。其次,学习源码阅读方法和培养源码习惯,可以使个人成为Redis专家,更快地适应代码更新和变化。此外,通过学习Redis源码,可以掌握C语言编码规范和技巧,提高代码质量。最重要的是,通过阅读Redis源码,可以学习到计算机系统设计思想,包括单机键值数据库和分布式系统的关键技术,从而提升职业竞争力。文章还介绍了阅读Redis源码的三个学习要点:获得代码全景图、在阅读代码前确定具体学习目标,并做好原理准备、在阅读代码时,先梳理出代码的主线逻辑,再详细学习分支细节。最后,文章还介绍了Redis的功能特性和课程设计,以及对读者的期望和鼓励。

2021-07-2648人觉得很赞给文章提建议

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Redis 源码剖析与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(42)

  • 最新
  • 精选
  • 悟空聊架构
    从最开始的 Redis 设计与实现 跟着看完,然后每篇都会做笔记,后来有幸被邀请参与了评稿和提意见,非常荣幸! 另外学习这个源码专栏,我也提个学习的小建议:配合 Redis 设计与实现这本书一起看,效果翻倍!

    作者回复: 握个手,很高兴认识审稿人:)

    2021-07-26
    7
    12
  • 可怜大灰狼
    记得自己是从2020年8月4日跟着老师学习《Redis核心技术和施展》。虽然我很菜,对比当时评论区大神Kaito的精彩回答,自己当时留言并不多。但是这一年来我一直在学习Redis,专栏也看了好几遍,源码也针对3.0版本看了好几遍,然后根据之前学习,都针对每章整理了相应xmind脑图。现在每天晚上为同为后端开发的朋友讲解Redis源码。真的非常感谢老师把我领进门。这次看到老师的第二个专栏,迫不及待购买,知道自己又可以补充脑图和源码讲解课。哈哈。

    作者回复: 加油,我们一起努力! 有问题也欢迎多多交流。

    2021-07-26
    4
  • kkby
    多久会更新完呢

    编辑回复: 同学你好,每周二、四、六更新,预计结课时间在十月底,同学可以跟随更新的节奏一起学习哦~

    2021-08-01
  • cake
    老师 此课一出 java面试又要增加难度了 哈哈哈哈

    作者回复: 额,话说为啥会增加java面试难度呢。。。

    2021-07-26
  • 耶马
    这期专栏分析的Redis 是哪个版本呢

    编辑回复: 同学好~课程中如果没有特殊说明,老师介绍的源码都是基于 Redis 5.0.8 版本的~

    2021-07-26
    2
  • 木几丶
    期待已久的redis第二季,果断第一时间订阅,希望跟着老师有所收获

    作者回复: 希望能给你带来些收获 :)

    2021-07-26
    2
  • Kaito
    看过第一季 Redis 专栏的朋友,应该都认识我了,去年在第一季 Redis 专栏被大家叫做「课代表」,在评论区持续输出了 4 个月之久,解答了很多 Redis 问题,另外还参与了专栏的「审稿、勘误」等工作。 当时很多人问我是怎么学习 Redis 的?我的回答中肯定少不了:「看源码」,想要进阶 Redis,我认为源码是必读的。 从去年到现在,这一晃,时间过得真快,现在 Redis 源码课来了,这次和大家一起,再次进阶 Redis!
    2021-07-27
    15
    105
  • 黄海峰
    也买了上一门课程,学完获益良多,10星好评,那时评论区还有个牛人分享很多经验,而当时我正好在某大厂负责一个分布式存储系统的开发维护,工作轻松舒适无需加班,还时刻可以摸鱼在外面边喝咖啡边收听极客时间,那种工作轻松又能摸鱼学习充实自己的时光真美好。。。后面疫情公司裁员一批人,从此沦落到小厂加班加点各种不适应,工作换了几次,年纪又大,技术也不是特别牛,游走于被行业淘汰边缘,浑浑噩噩了一阵,产生了转行的念头并打算开始设法实施,现在又看到老师新课,熟悉的声音熟悉的知识点让我回忆反思了很多,虽然境况已经大不相同,但肯定还是要购买学习的,对我的意义已经不只是增强技术顺利面试了,还是一种精神寄托啊。
    2021-07-26
    26
  • 不负青春不负己🤘
    话说源码必须懂C吧,我的C已经还给大学老师-_-||
    2021-07-26
    2
    6
  • 小人物大希望
    可以参考这篇文章,用CLion+ComplieDB,把Redis的代码给跑起来,这样就方便多了,https://blog.jetbrains.com/clion/2018/08/working-with-makefiles-in-clion-using-compilation-db/
    2021-08-22
    1
    5
收起评论
大纲
固定大纲
会用 Redis 不就行了,为啥要读源码呢?
如何正确学习 Redis 源码?
这门课程是怎样设计的?
写在最后
显示
设置
留言
42
收藏
65
沉浸
阅读
分享
手机端
快捷键
回顶部