基于 clangd 搭建 Redis 6.2 源码阅读与调试环境

文章目录

一、前言

Redis 是用 C 语言实现的项目,想要深入阅读和理解其源码,必须先完成源码编译、调试环境配置以及代码跳转功能的准备。

二、编译准备与工具安装

2.1 获取Redis 6.2 源码

bash 复制代码
# 克隆 Redis 源
git clone https://github.com/redis/redis.git -b 6.2
cd redis-6.2

# 编译 Redis
make

# 运行测试(可选,不进行测试,容易出错)
# make test

# 安装到系统目录
sudo make install

2.2 工具安装

编译源码需先安装 bearclangd 两个核心工具,前者用于生成编译信息文件,后者配合 VSCode 实现源码解析与跳转。

工具 1:bear

bear 的作用是在编译过程中记录编译命令,生成 compile_commands.json 文件(后续 clangd 需依赖该文件解析源码)。安装命令如下:

shell 复制代码
sudo apt install bear

工具 2:clangd

clangd 是一款 C/C++ 语言的代码补全、跳转工具,需同时安装 "VSCode 前端插件" 和 "系统后端程序",且需指定版本并设为默认。

  1. 打开 VSCode → 按 Ctrl+Shift+X 打开 "扩展" 面板 → 搜索 "clangd" → 选择作者为 "LLVM" 的插件(图标是蓝色的 "clangd" 字样)→ 点击 "安装"。

  2. 安装指定版本的 clangd 后端(以 clangd-12 为例,也可选择 14、15 等版本):

    bash 复制代码
    sudo apt-get install clangd-12
  3. 将安装的版本设为系统默认 clangd

    bash 复制代码
    sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-12 100
  4. 验证安装:执行 clangd --version,如果输出版本信息(如 clangd version 12.0.0),则说明安装成功。

注意: 禁用冲突的 VSCode 扩展

VSCode 自带的 "C/C++" 扩展(作者是 Microsoft)可能会和 clangd 冲突。

禁用 IntelliSense 功能:

如果还想保留微软插件用于调试,但只让 clangd 管理语法高亮:

  1. 打开 VSCode 设置(Ctrl+,)
  2. 搜索 "C_Cpp.intelliSenseEngine"
  3. 设置为 "disabled"
    (或者在 .vscode/settings.json 里加上)
json 复制代码
{
  "C_Cpp.intelliSenseEngine": "disabled",
  "C_Cpp.errorSquiggles": "disabled"
}

重启 vscode,这样微软插件不再解析代码(也不会报红),clangd 完全负责语法分析。

2.3 编译

进入 Redis 源码根目录下执行

bash 复制代码
cd redis-6.2
make clean
bear make

执行完成后,项目根目录中会生成 compile_commands.json 文件。

打开源文件,头文件下方出现一条下划线,说明 clangd 已经成功解析头文件;按住 Ctrl + 左键,即可精确跳转到函数或变量的声明位置,提高源码阅读效率。

2.4 VSCode 调试环境配置

1. 配置 tasks.json(编译任务,确保调试前自动编译)

tasks.json 的作用是:每次启动调试前,自动执行 bear make 重新编译,保证代码是最新的。替换 tasks.json 的内容为以下代码:

json 复制代码
{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "cppbuild",
      "label": "build-redis",  // 任务名称,后续 launch.json 要用到,不能改
      "command": "bear",        // 执行的命令:bear
      "args": ["make"],         // 命令参数:make(即执行 bear make)
      "options": {
        "cwd": "${workspaceFolder}"  // 编译目录:当前打开的源码根目录(无需改)
      },
      "problemMatcher": ["$gcc"],    // 识别 gcc 编译错误
      "group": {
        "kind": "build",
        "isDefault": true       // 设为默认编译任务
      },
      "detail": "调试前自动编译 Redis 源码"
    }
  ]
}

2. 配置 launch.json(调试参数,指定调试哪个程序)

launch.json 的作用是:告诉 VSCode 用哪个程序(redis-server)、哪个调试器(GDB)、带什么参数(redis.conf)启动调试。替换 launch.json 的内容为以下代码:

json 复制代码
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "启动 redis",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/src/redis-server",
            "args": ["redis.conf"],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build-redis",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

三、启动调试

完成上述配置后,在 VSCode 中按 F5 或点击"运行 -> 启动调试",即可开始调试 Redis 服务器。当服务器启动后,可以在 VSCode 的调试侧边栏或底部终端中观察到 Redis 创建的多线程环境。

  • redis-server:这是 Redis 的主线程,负责处理命令请求、执行事务、运行 Lua 脚本等核心逻辑。
  • bio_close_file:阻塞 IO 线程,负责关闭文件(避免主线程卡壳)。
  • bio_aof_fsync:阻塞 IO 线程,负责在 AOF 持久化模式下,异步将 AOF 文件缓冲区数据刷到磁盘,确保数据持久化。
  • bio_lazy_free:阻塞 IO 线程,负责异步释放大内存块(比如删除很大的键)。
  • io_thd_* :这是 Redis 6.0 引入的 I/O 多线程。主要负责处理网络 I/O,即读取请求数据和写回响应数据,以此减轻主线程的网络负载。
  • jemalloc_bg_thd:这是 Redis 所使用的 jemalloc 内存池内部开启的后台线程,用于执行内存碎片整理等维护任务。

补充:

Redis 6.0+ 引入了 IO 多线程(用于加速网络 IO 读写),但该功能默认是关闭的 ,需要手动在配置文件中开启,否则不会创建 io_thd_* 相关线程。

需编辑 Redis 的配置文件 redis.conf(即调试时指定的 redis.conf),开启 IO 多线程相关配置:

  1. 找到并修改 io-threads-do-reads :在 redis.conf 中搜索(Ctrl + F) io-threads-do-reads,默认值是 no,将其改为 yes,表示 "启用 IO 多线程处理读操作"。

  2. 配置 IO 线程数量 io-threads :继续在 redis.conf 中搜索 io-threads,默认值是 1(即仅主线程处理 IO)。可根据 CPU 核心数调整,例如设置为 4(建议值 ≤ CPU 核心数,比如 4 核 CPU 设为 4)。

示例配置:

conf 复制代码
io-threads-do-reads yes 
io-threads 4

保存 redis.conf 后,重新启动调试

相关推荐
Elastic 中国社区官方博客16 小时前
在 Elasticsearch 中使用 Mistral Chat completions 进行上下文工程
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
编程爱好者熊浪17 小时前
两次连接池泄露的BUG
java·数据库
cr7xin18 小时前
缓存三大问题及解决方案
redis·后端·缓存
大佬,救命!!!19 小时前
C++多线程同步与互斥
开发语言·c++·学习笔记·多线程·互斥锁·同步与互斥·死锁和避免策略
爱怪笑的小杰杰19 小时前
浏览器端缓存地图请求:使用 IndexedDB + ajax-hook 提升地图加载速度
ajax·okhttp·缓存
TDengine (老段)19 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
赵文宇(温玉)19 小时前
构建内网离线的“github.com“,完美解决内网Go开发依赖
开发语言·golang·github
qq74223498419 小时前
Python操作数据库之pyodbc
开发语言·数据库·python
Joker1008519 小时前
仓颉自定义序列化:从原理到高性能多协议实现
开发语言
Adellle19 小时前
2.单例模式
java·开发语言·单例模式