Skip to content

阻塞与故障排查 ​

线上 Redis 变慢或异常,需要一套系统的方法快速定位根因。本章介绍排查工具与常见故障的定位思路,给出可复用的排查流程。

排查时先按延迟、内存、CPU、连接和集群状态分流,再收集 INFO、SLOWLOG、系统指标和客户端错误形成证据链。确认根因后再修改配置;如果指标恢复但原因未验证,应继续记录假设和反证,避免把偶然恢复当成修复完成。

1. 排查工具箱 ​

工具用途开销
INFO服务器状态全貌低
SLOWLOG慢查询日志低
MONITOR实时命令流高(生产慎用)
CLIENT LIST客户端连接详情中
redis-cli --latency持续 PING 的往返延迟低
redis-cli --bigkeys大 Key 扫描中(SCAN 遍历)
DEBUG OBJECT key单 Key 的编码与引用信息生产环境慎用;受版本、安全策略和命令禁用影响
MEMORY USAGE key单 key 内存占用低
bash
# 快速全貌
redis-cli INFO all > /tmp/redis-info.txt

# 命令统计(找出耗时最高的命令)
INFO commandstats
# cmdstat_set:calls=1000000,usec=50000,usec_per_call=0.05
# cmdstat_keys:calls=10,usec=500000,usec_per_call=50000.00  ← 这个有问题

2. 排查方法论 ​

txt
观察现象 → 收集指标 → 提出假设 → 验证假设 → 修复 → 监控
步骤说明
观察现象明确是延迟、内存还是 CPU 问题
收集指标用 INFO、SLOWLOG 收集客观数据
提出假设基于指标缩小范围(慢命令?fork?swap?)
验证假设用数据证实或推翻,不凭直觉
修复替换慢命令、调配置、扩内存
监控修复后持续观察,确认问题消除

3. 延迟突增排查 ​

延迟突增是最常见的故障,按顺序排查:

3.1 慢命令 ​

bash
SLOWLOG GET 10
# 如果看到 KEYS *、HGETALL 大 Hash → 用 SCAN 替代
# 如果看到 DEL 大 Key → 用 UNLINK 替代

3.2 fork 停顿 ​

bash
INFO stats | grep latest_fork_usec
# latest_fork_usec:150000  → fork 耗时 150ms,结合业务延迟基线判断

# 解决方案:
# 1. 根据页表规模、COW 和延迟预算评估实例拆分
# 2. 调整持久化触发条件并避开写入高峰
# 3. 评估副本分担持久化任务的可行性和数据恢复影响

3.3 AOF fsync 阻塞 ​

bash
# 检查 fsync 延迟
redis-cli INFO persistence | grep aof_delayed_fsync
# aof_delayed_fsync:5  → 5 次 fsync 延迟

# 解决方案:
# 1. appendfsync 改为 everysec(不要 always)
# 2. 使用 SSD 替代 HDD
# 3. 评估 no-appendfsync-on-rewrite;它会扩大重写期间的数据丢失窗口

3.4 swap 导致的延迟 ​

bash
# RSS 高于 used_memory 也可能来自分配器碎片,不能据此判定 swap
INFO memory | grep -E "used_memory|mem_fragmentation_ratio"

# 检查目标 Redis 进程实际换出的页(将 12345 替换为目标 PID)
awk '/^Swap:/ {sum += $2} END {print sum " kB"}' /proc/12345/smaps

# 检查系统 swap 使用量
grep -E "SwapTotal|SwapFree" /proc/meminfo

swap 的解决:增加物理内存,或减小 maxmemory。

4. 内存异常排查 ​

现象可能原因排查方法
内存持续增长key 无 TTL 堆积INFO keyspace 看 key 数量趋势
碎片率高(>1.5)频繁增删 keyINFO memory 的 mem_fragmentation_ratio
使用了 swap容器或主机可用内存不足检查进程 smaps 的 Swap: 与系统 SwapTotal/SwapFree
内存突增大 Key 写入redis-cli --bigkeys 扫描
bash
# 查看各 DB 的 key 数量
INFO keyspace
# db0:keys=1000000,expires=800000,avg_ttl=300000
# db1:keys=50,expires=0,avg_ttl=0

# 查看内存分布
INFO memory
# used_memory:1073741824
# used_memory_rss:1610612736
# used_memory_peak:2147483648
# mem_fragmentation_ratio:1.50

5. CPU 飙升排查 ​

排查点命令说明
高频命令INFO commandstats找出调用频繁、耗时高的命令
Lua 脚本SLOWLOG脚本执行期间独占 CPU
频繁 BGSAVEINFO statsfork 与 COW 消耗 CPU
过期键风暴INFO statsexpired_keys 突增
bash
# 实时观察目标 Redis 进程 CPU(将 12345 替换为目标 PID)
top -p 12345

# Redis 内部 CPU 统计
INFO cpu
# used_cpu_sys:1234.56
# used_cpu_user:5678.90

6. 连接数异常 ​

现象可能原因排查
连接数过高连接池泄漏、短连接CLIENT LIST 统计
连接被拒达到 maxclientsCONFIG GET maxclients
TIME_WAIT 堆积频繁短连接ss -s 系统层面
bash
# 统计连接来源
CLIENT LIST | awk '{print $2}' | sort | uniq -c | sort -rn

# 查看最大连接数
CONFIG GET maxclients

7. 集群故障排查 ​

现象可能原因排查
MOVED 重定向频繁槽分配不均CLUSTER SLOTS
ASK 重定向槽迁移中CLUSTER STATE
节点下线网络或内存问题CLUSTER NODES
数据不一致复制延迟INFO replication

Released under the MIT License.