01 - 使用VS Code调试Redis源码
02 - Redis源码结构介绍
这两年Redis已经取代Mysql成为我工作中最常接触的基础组件了。但使用的越多,疑惑之处也越多。
首先是高可用,sentinel机制究竟是什么样的?Redis实例上线下线的过程中能够保证数据不丢失么?
其次是各个数据结构的细节,比如一个SET能够容纳多少数据?会不会在达到某个阈值之后性能断崖式下降?
第三是持久化机制,在生产中遇到了执行RDB导致Redis主从切换,所以特别需要了解其执行细节。
当然还有许多其他疑问不一一列举了。虽然网上也有很多文章介绍这些功能以及原理,但我觉得深入源码之后才能知其所以然,再遇到问题就能从更本质的角度去分析。
以上就是我开始阅读Redis源码的缘由。
首先是《Redis设计与实现》一书,深度,广度。我认为可以大致翻阅一遍,之后将其作为工具书,想了解哪块的知识就去对应的章节看。
其次是一门课程Redis 源码剖析与实战,在写阅读笔记的时候我还没学完。从我读到一半的体验来看,每一章节的信息量都很大,但整体来看还是显得零散。可能是这类课程的通病吧,每一章都必须要对应一个知识点。
最后是《C Primer Plus》。因为一直以来主力语言是Java,对于C的语法,尤其是指针这些知识完全陌生,还有C的编译调试也没有概念。这本书正好用来作为学习C语言的参考。
还有一些博文、教程会在具体的篇目中单独列出来。
无论是看的书还是课程,上来就直接都是直接看源码了,但我希望能够debug源码,看执行一个命令的时候函数到底是怎样跳转的才能更容易理解源码。
我使用的 redis-3.0-annotated是《Redis设计与实现》一书的配套材料,虽然当前(2022年5月份)Redis 7.0已经发布,但3.0版本已基本包含了Redis重要功能。相比于官方源码,这个仓库的代码加上了中文注释,阅读代码会更容易。
git clone https://github.com/huangz1990/redis-3.0-annotated.git
首先确认VS Code已安装 C/C++、C/C++ Extension Pack 插件
添加配置Run
-> Add Configuration
在launch.json
中添加以下信息
{
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/redis-server",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb"
}
]
}
笔者使用的是Mac笔记本,使用lldb
作为C语言编译器因此MIMode
设置为lldb
,如果使用Linux的话可以修改为gbd
,但要注意先安装编译器。
以Ubuntu为例,执行以下命令安装 gcc
g++
以及 make
:
sudo apt install build-essential
接下来要从源码编译成可执行程序,这里使用VS Code的任务(Task)。选择“终端”(Terminal) -> “运行编译任务”(Run Build Task) -> 从模版创建json
在生成的tasks.json
文件中填入以下内容:
{
"version":"2.0.0",
"tasks":[
{
"label":"Build",
"type":"shell",
"command":"make",
"args":[
"CFLAGS=\"-g -O0\""
],
"problemMatcher":[
],
"group":{
"kind":"build",
"isDefault":true
}
}
]
}
之后可以在 “终端”(Terminal) -> “运行编译任务”(Run Build Task) 执行编译任务了。
如果不使用VS Code的任务,则可以直接在源码根目录执行以下命令,也可以执行编译。
make CFLAGS="-g -O0"
编译完成后,在redis-3.0-annotated/src
目录下可以看到生成了许多后缀为.o
的文件以及执行文件redis-server
、redis-sentinel
、redis-cli
等。
之后在“运行”(Run)->“开始调试”(Start Debugging),服务正常启动,我们就可以在VS Code中调试源码了。