*Redis 调试指南
Redis 提供多种调试工具和方法,帮助开发者和运维人员诊断问题。
*DEBUG 命令
Redis 提供 DEBUG 命令用于各种调试操作。
*DEBUG SEGFAULT
使 Redis 服务器崩溃,模拟段错误。用于测试崩溃恢复机制:
redis-cli debug segfault
警告:仅用于测试环境!
*DEBUG OOM
使 Redis 耗尽内存:
redis-cli debug oom
*DEBUG LOADAOF
重新加载 AOF 文件:
redis-cli debug loadaof
*DEBUG RELOAD
保存 RDB 文件并重新加载:
redis-cli debug reload
可选参数:
NOSAVE:不保存当前数据集MERGE:将当前数据集与磁盘上的数据集合并
*DEBUG OBJECT
获取键的内部信息:
redis-cli debug object mykey
输出示例:
Value at:0x7f8b4c0b4030 refcount:1 encoding:raw serializedlength:5 lru:16486158 lru_seconds_idle:0
字段说明:
Value at:值的内存地址refcount:引用计数encoding:内部编码(raw、int、embstr、ziplist 等)serializedlength:序列化后的长度lru:LRU 时钟值lru_seconds_idle:空闲秒数
*DEBUG SDSLEN
获取 SDS(Simple Dynamic String)长度信息:
redis-cli debug sdslen mykey
*DEBUG POPULATE
用随机键填充数据库(用于测试):
# 创建 100000 个随机键
redis-cli debug populate 100000
# 创建指定前缀的键
redis-cli debug populate 100000 myprefix 10
*DEBUG SLEEP
让 Redis 睡眠指定秒数(用于测试):
redis-cli debug sleep 10
*DEBUG SET-ACTIVE-EXPIRE
启用或禁用主动过期:
redis-cli debug set-active-expire 0 # 禁用
redis-cli debug set-active-expire 1 # 启用
*DEBUG QUICKLIST-PACKED-THRESHOLD
设置 quicklist 压缩阈值:
redis-cli debug quicklist-packed-threshold 2kb
*日志调试
*日志级别
Redis 支持以下日志级别:
debug:大量信息,用于开发/调试verbose:许多信息,但不如 debug 多notice:适度详细,生产环境推荐warning:仅记录非常重要/关键的消息
配置:
redis-cli config set loglevel debug
*慢查询日志
记录执行时间超过指定阈值的命令:
# 设置阈值(微秒)
redis-cli config set slowlog-log-slower-than 10000
# 设置日志长度
redis-cli config set slowlog-max-len 128
# 查看慢查询日志
redis-cli slowlog get 10
# 查看慢查询日志长度
redis-cli slowlog len
# 清空慢查询日志
redis-cli slowlog reset
慢查询日志条目格式:
1) 1) (integer) 1 # 唯一 ID
2) (integer) 1648615800 # 时间戳
3) (integer) 12345 # 执行时间(微秒)
4) 1) "GET" # 命令
2) "mykey" # 参数
*使用 GDB 调试
*附加到运行中的 Redis
# 找到 Redis PID
pgrep redis-server
# 使用 GDB 附加
sudo gdb -p <redis-pid>
*常用 GDB 命令
# 查看调用栈
bt
# 查看所有线程
info threads
# 切换到特定线程
thread 1
# 查看变量
p server
# 设置断点
b processCommand
# 继续执行
c
# 单步执行
n
# 打印当前命令
p (struct redisCommand *)c->cmd
*生成核心转储
# 启用核心转储
ulimit -c unlimited
# 配置核心转储路径
echo '/var/crash/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern
# 触发段错误(测试)
redis-cli debug segfault
*分析核心转储
gdb /usr/local/bin/redis-server /var/crash/core.redis-server.1234
(gdb) bt full # 完整调用栈
(gdb) info registers # 寄存器信息
(gdb) x/20i $pc # 反汇编当前位置
*使用 Valgrind
Valgrind 是内存错误检测工具,可用于检测 Redis 的内存问题。
*安装
sudo apt-get install valgrind
*使用
# 基本使用
valgrind --leak-check=full redis-server /etc/redis/redis.conf
# 详细输出
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=valgrind.log redis-server /etc/redis/redis.conf
# 仅检测内存错误(更快)
valgrind --tool=memcheck redis-server /etc/redis/redis.conf
注意:Valgrind 会显著降低 Redis 性能,仅用于测试环境。
*使用 strace
strace 跟踪系统调用,可用于诊断 I/O 问题。
# 跟踪 Redis 系统调用
sudo strace -p $(pgrep redis-server)
# 跟踪文件操作
sudo strace -e trace=file -p $(pgrep redis-server)
# 跟踪网络操作
sudo strace -e trace=network -p $(pgrep redis-server)
# 跟踪内存操作
sudo strace -e trace=memory -p $(pgrep redis-server)
# 记录到文件
sudo strace -o redis.strace -p $(pgrep redis-server)
*使用 ltrace
ltrace 跟踪库函数调用:
sudo ltrace -p $(pgrep redis-server)
*网络调试
*使用 tcpdump
# 捕获 Redis 流量
sudo tcpdump -i any port 6379 -w redis.pcap
# 分析
sudo tcpdump -r redis.pcap -A | head -20
*使用 Wireshark
- 使用 tcpdump 捕获流量
- 在 Wireshark 中打开
- 使用 Redis 协议解析器(如果可用)
*使用 redis-cli 的 raw 模式
# 查看原始协议数据
redis-cli --raw monitor
# 使用管道测试
redis-cli --pipe < commands.txt
*内存调试
*使用 jemalloc 的 prof 功能
# 编译时启用
make MALLOC=jemalloc CFLAGS="-DJE_MALLOC_PROF"
# 生成堆转储
redis-cli debug mallctl prof.dump
*使用 massif(Valgrind 工具)
valgrind --tool=massif redis-server /etc/redis/redis.conf
ms_print massif.out.* > massif.txt
*性能调试
*使用 perf
# 记录性能数据
sudo perf record -g -p $(pgrep redis-server) -- sleep 60
# 生成报告
sudo perf report
# 生成火焰图
sudo perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > redis.svg
*使用 eBPF/bcc
# 安装 bcc
cd /usr/share/bcc/tools
# 跟踪 Redis 的 off-CPU 时间
./offcputime -p $(pgrep redis-server) 30
# 跟踪 Redis 的文件系统操作
./biosnoop -p $(pgrep redis-server)
# 跟踪 Redis 的内存分配
./memleak -p $(pgrep redis-server)
*Lua 脚本调试
*使用 EVAL 调试
# 测试脚本
redis-cli eval "return redis.call('ping')" 0
# 打印调试信息
redis-cli eval "redis.log(redis.LOG_DEBUG, 'debug message') return 1" 0
*Lua 日志级别
redis.log(redis.LOG_DEBUG, "debug message")
redis.log(redis.LOG_VERBOSE, "verbose message")
redis.log(redis.LOG_NOTICE, "notice message")
redis.log(redis.LOG_WARNING, "warning message")
日志输出到 Redis 日志文件。
*模块调试
*加载模块
redis-cli module load /path/to/module.so
*查看已加载模块
redis-cli module list
*卸载模块
redis-cli module unload <module-name>
*测试工具
*redis-cli 测试模式
# 扫描数据库
redis-cli --scan --pattern 'user:*'
# 大键扫描
redis-cli --bigkeys
# 内存键扫描
redis-cli --memkeys
# 统计模式
redis-cli --stat
*使用 Redis 测试套件
# 运行测试
cd redis-src
cd tests
./run-tests
# 运行特定测试
./run-tests --single unit/type/string
*调试最佳实践
始终在非生产环境测试调试命令
- DEBUG SEGFAULT、
DEBUG OOM等命令会导致服务器崩溃
- DEBUG SEGFAULT、
使用日志级别递增
- 从
notice开始,必要时提高到verbose或debug
- 从
收集完整信息
- Redis 版本、操作系统、配置文件、日志、崩溃转储
使用版本控制
- 在修改配置前备份
- 记录所有更改
监控关键指标
- 内存使用、CPU 使用、延迟、连接数
使用适当的工具
- 内存问题:Valgrind、jemalloc prof
- 性能问题:perf、flamegraph
- 网络问题:tcpdump、Wireshark
- 崩溃问题:GDB、核心转储