读懂Redis源码,我总结了这7点心得

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 读懂Redis源码,我总结了这7点心得

读代码就好比去一个陌生城市旅行,这个旅途过程充满着未知。如果在出发之前,我们手里能有一张地图,那我们对自己的行程就可以有一个非常清晰的规划。

我们就知道,如果想要到达目的地,需要从哪里出发、经过哪些地方、通过什么方式才能到达,有了地图就有了行进方向,否则很容易迷失。

因此,提前花一些时间梳理整个项目的「结构和目录」,对于后面更好地阅读代码是非常有必要的。

就拿 Redis 来举例,在读 Redis 源码之前,我们可以先梳理出整个项目的功能模块,以及每个模块对应的代码文件(src 下的代码结构):

这样,有了这张地图之后,我们再去看代码的时候,就可以有重点地阅读了。

02 前置知识准备

=========

在梳理完整个项目结构之后,我们就可以正式进入阅读环节当中了。不过,在阅读代码之前,我们其实还需要预先掌握一些「前置知识」。

因为一个完整的项目,必然综合了各个领域的技术知识点,比如数据结构、操作系统、网络协议、编程语言等,如果我们提前做好一些功课,在读源码的过程中就会轻松很多。

需要zi料+ 绿色徽【vip1024b】

以下是根据我在阅读 Redis 书籍和实战过程中,提取的读源码必备前置知识点,你可以参考下:

  • 常用数据结构:数组、链表、哈希表、跳表
  • 网络协议:TCP 协议
  • 网络 IO 模型:IO 多路复用、非阻塞 IO、Reactor 网络模型
  • 操作系统:写时复制(Copy On Write)、常见系统调用、磁盘 IO 机制
  • C 语言基础:循环、分支、结构体、指针

当然,在阅读源码的过程中,我们也可以根据实际问题再去查阅相关资料,但不管怎样,提前熟悉这些方面的知识,在真正读代码时就会省下不少时间。

03 从基础模块开始读

===========

好,有了地图并掌握了前置知识之后,接下来我们就要进入主题了:读代码

但具体要从哪个地方开始读起呢?我认为要先从「最基础」的模块开始读起。

我在前面也分析了,一个完整的项目会划分很多的功能模块,但这些模块并不是孤立的,而很可能是有「依赖」关系的。

比如说,Redis 中的 networking.c 文件,表示处理网络 IO 的具体实现。而如果我们能在理解事件驱动模块 ae.c 的基础上,再去阅读网络 IO 模块,效率就会更高。

那在 Redis 源码中,哪些是最基础的模块呢?

想一下,我们在使用 Redis 时,接触最频繁的是哪些功能?

答案是各种数据类型

一切操作的基础,其实都是基于这些最常用的数据类型来做的,比如 String、List、Hash、Set、Sorted Set等。所以,我们就可以从这些基础模块开始读起,也就是从 t_string.c、t_list.c、t_hash.c、t_set.c、t_zset.c 代码入手。

如果你对 Redis 的数据类型有所了解,就会看到这些数据类型在实现时,底层都对应了不同的数据结构。比如,String 的底层是 SDS,List 的底层是 ziplist + quicklist,Hash 底层可能是ziplist,也可能是哈希表,等等。

由此一来,我们会发现,这些数据结构又是更为「底层」的模块,所以我们在阅读数据类型模块时,就需要重点聚焦在这些模块上,也就是 sds.c、ziplist.c、quicklist.c、dict.c、intset.c 文件,而且这些文件都是比较独立的,阅读起来就可以更加集中。

这样,当我们真正掌握了这些「底层数据结构」的实现后,就能更好地理解基于它们实现的各种「数据类型」了。

这些基础模块就相当于一座大厦的地基,地基打好了,才能做到高楼耸立。

04 找到核心主线

=========

接着,掌握了数据结构模块之后,这时我们的重点就需要放在「核心主线」上来了。

在这个阶段,我们需要找到一个明确的目标,以这个目标为主线去读代码。因为读源码一个很常见的需求,就是为了了解这个项目最「核心功能」的实现细节,我们只有以此为目标,找到这条主线去读代码,才能达到最终目的。

那么在读 Redis 源码时,什么才是它的核心主线呢?这里我分享一个非常好用的技巧,就是根据「Redis 究竟是怎么处理客户端发来的命令的?」 为主线来梳理。

举个例子,当我们在执行 SET testkey testval EX 60 这样一条命令时,就需要搞清楚 Redis 是怎么执行这条命令的。

也就是要明确,Redis 从收到客户端请求,到把数据存到 Redis 中、设置过期时间,最后把响应结果返回给客户端,整个过程的每一个环节,到底是如何处理的。

有了这条主线,我们就有了非常明确的目标,而且沿着这条主线去读代码,我们还可以很清晰地把多个模块「串联」起来。比如从前面的例子中,我们会看到一条命令的执行,主要包含了这样几个阶段。

  • Redis Server 初始化:加载配置、监听端口、注册连接建立事件、启动事件循环(server.c、anet.c)。
  • 接收、解析客户端请求:初始化 client、注册读事件、读客户端 socket(networking.c)。
  • 处理具体的命令:找到对应的命令函数、执行命令(server.c、t_string.c、t_list.c、t_hash.c、t_set.c、t_zset.c)。
  • 返回响应给客户端:写客户端缓冲区、注册写事件、写客户端 socket(networking.c)。

沿着这条主线去读代码,我们就可以掌握一条命令的执行全过程。

而且,由于这条主线的代码逻辑,已经覆盖了「所有命令」的执行流程,我们下次再去读其它命令时,比如 SADD,就只需要关注「处理命令」部分的逻辑即可,其它逻辑有 80% 都是相同的。

05 先整体后细节

=========

当然,在阅读主线代码的过程中,肯定也会遇到过于「复杂」的函数,第一次在读这种函数时,很容易就会「陷进去」,导致整个主线代码的阅读,无法继续推进下去。

遇到这种情况其实是很正常的,可这时我们应该怎么办呢?

这里我的做法是,前期读到这种逻辑时,不要马上陷入到细节中去,而是要先「抓整体」。

具体来说,对于复杂的函数逻辑,我们刚开始并不需要知道它的每一个细节是如何实现的,而是只需知道这个函数「大致」做了几件事情即可。

举个例子,在执行 HSET 命令时,有一段代码很复杂,其中包括了很多分支判断,一次很难读懂:

那么,我在读这段代码时,就可以先简化逻辑,把握整体思路:

完结

Redis基于内存,常用作于缓存的一种技术,并且Redis存储的方式是以key-value的形式。Redis是如今互联网技术架构中,使用最广泛的缓存,在工作中常常会使用到。Redis也是中高级后端工程师技术面试中,面试官最喜欢问的问题之一,因此作为Java开发者,Redis是我们必须要掌握的。

Redis 是 NoSQL 数据库领域的佼佼者,如果你需要了解 Redis 是如何实现高并发、海量数据存储的,那么这份腾讯专家手敲《Redis源码日志笔记》将会是你的最佳选择。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
存储 NoSQL 算法
Redis系列-13.Redis经典五大类型源码及底层实现(一)(上)
Redis系列-13.Redis经典五大类型源码及底层实现(一)
76 0
|
3月前
|
存储 NoSQL Redis
redis源码学习
redis源码学习
|
30天前
|
存储 NoSQL 算法
【Redis技术进阶之路】「底层源码解析」揭秘高效存储模型与数据结构底层实现(字典)(二)
【Redis技术进阶之路】「底层源码解析」揭秘高效存储模型与数据结构底层实现(字典)
47 0
|
3月前
|
NoSQL 网络协议 Linux
Redis单线程源码深入解析
Redis单线程源码深入解析
|
3月前
|
NoSQL Linux Redis
redis源码调试---vscode使用技巧-----C语言跳转到函数定义
redis源码调试---vscode使用技巧-----C语言跳转到函数定义
71 0
|
10天前
|
人工智能 前端开发 Java
Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码
智慧导诊解决盲目就诊问题,减轻分诊工作压力。降低挂错号比例,优化就诊流程,有效提高线上线下医疗机构接诊效率。可通过人体画像选择症状部位,了解对应病症信息和推荐就医科室。
151 10
|
3月前
|
缓存 NoSQL 关系型数据库
Redis 7.0 源码调试环境搭建与源码导读技巧
Redis 7.0 源码调试环境搭建与源码导读技巧
54 0
|
3月前
|
NoSQL 算法 Redis
redis7.0源码阅读(五):跳表(skiplist)
redis7.0源码阅读(五):跳表(skiplist)
62 1
|
3月前
|
负载均衡 NoSQL Java
redis7.0源码阅读(四):Redis中的IO多线程(线程池)
redis7.0源码阅读(四):Redis中的IO多线程(线程池)
77 0
|
3月前
|
存储 NoSQL Redis
redis7.0源码阅读(三):哈希表扩容、缩容以及rehash
redis7.0源码阅读(三):哈希表扩容、缩容以及rehash
76 0

热门文章

最新文章