强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

20 - 排错指南

排错指南

20.1 常见连接问题

问题一:无法连接 Redis

# 症状
redis-cli -h 192.168.1.100 ping
# Error: Connection refused

# 排查步骤
# 1. 检查 Redis 是否运行
systemctl status redis-server
ps aux | grep redis-server

# 2. 检查绑定地址
redis-cli CONFIG GET bind
# 如果是 127.0.0.1,外部无法访问

# 3. 检查端口
netstat -tlnp | grep 6379
ss -tlnp | grep 6379

# 4. 检查防火墙
sudo iptables -L -n | grep 6379
sudo ufw status

# 5. 检查 protected-mode
redis-cli CONFIG GET protected-mode

问题二:认证失败

# 症状
redis-cli SET key value
# (error) NOAUTH Authentication required.

# 解决
redis-cli -a yourpassword
# 或
redis-cli
AUTH yourpassword

# Redis 6.0+ ACL 错误
# (error) WRONGPASS invalid username-password pair or user is disabled.
ACL LIST                    # 检查用户列表
ACL WHOAMI                  # 查看当前用户

问题三:连接数过多

# 症状
# (error) ERR max number of clients reached

# 排查
redis-cli INFO clients | grep connected_clients
redis-cli CLIENT LIST | wc -l

# 解决
redis-cli CONFIG SET maxclients 20000

# 查看客户端连接详情
redis-cli CLIENT LIST
# id=1 addr=192.168.1.100:54321 fd=8 name= idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=ping

# 找出空闲时间最长的连接
redis-cli CLIENT LIST | awk '{print $4}' | sort -t= -k2 -nr | head -10

20.2 延迟问题排查

使用 redis-cli 诊断

# 1. 延迟测试
redis-cli --latency
# min: 0, max: 1, avg: 0.19 (264 samples)

# 2. 延迟历史
redis-cli --latency-history
# min: 0, max: 1, avg: 0.19 (132 samples) -- 15.00 seconds range

# 3. 延迟分布图
redis-cli --latency-dist

# 4. 内部延迟基准
redis-cli --intrinsic-latency 5
# 5 seconds of testing...
# 128 microseconds per call (best of 1000 calls)

慢查询分析

# 获取慢查询日志
redis-cli SLOWLOG GET 10

# 输出解析
# 1) 1) (integer) 1              # 日志 ID
#    2) (integer) 1715318400     # 时间戳
#    3) (integer) 15230          # 耗时(微秒)
#    4) 1) "KEYS"                # 命令
#       2) "*"
#    5) "127.0.0.1:54321"        # 客户端地址

# 慢查询日志长度
redis-cli SLOWLOG LEN

# 重置慢查询日志
redis-cli SLOWLOG RESET

# 检查最近的 fork 耗时
redis-cli INFO stats | grep latest_fork_usec
# latest_fork_usec:1500  ← 1.5ms,正常

延迟原因分析表

原因症状解决方案
慢命令SLOWLOG 中出现 O(N) 命令避免 KEYS *、大 HGETALL
大 KeyDEL/HDEL 阻塞使用 UNLINK 异步删除
fork 操作BGSAVE 期间延迟增大减小实例内存、关闭 THP
网络延迟客户端到 Redis 延迟高使用 Pipeline、就近部署
内存 swap延迟波动大增加内存、设置 maxmemory
AOF fsyncappendfsync always改用 everysec
客户端连接数过多连接数 > 5000使用连接池
CPU 绑定问题多核利用率不均绑定 CPU 核心

延迟监控(LATENCY MONITOR)

# 启动延迟监控
redis-cli CONFIG SET latency-monitor-threshold 5  # 5ms

# 查看延迟事件
redis-cli LATENCY LATEST
# 1) 1) "command"
#    2) (integer) 1715318400
#    3) (integer) 15    # 延迟(毫秒)
#    4) (integer) 15    # 最大延迟

# 查看延迟历史
redis-cli LATENCY HISTORY command

# 延迟图形化(ASCII 图)
redis-cli LATENCY GRAPH command

20.3 内存问题排查

问题一:内存占用过高

# 1. 查看内存概况
redis-cli INFO memory
# used_memory_human:4.50G
# used_memory_peak_human:6.20G
# mem_fragmentation_ratio:1.25

# 2. 找出大 Key
redis-cli --bigkeys --i 0.1

# 3. 检查内存碎片率
redis-cli INFO memory | grep mem_fragmentation_ratio
# > 1.5 → 碎片严重,需要整理
# < 1.0 → 使用了 swap,非常危险

# 4. 开启碎片整理(Redis 4.0+)
redis-cli CONFIG SET activedefrag yes

# 5. 检查淘汰情况
redis-cli INFO stats | grep evicted_keys
# evicted_keys:0 → 无淘汰
# > 0 → 内存不足,正在淘汰

问题二:内存泄漏

# 症状:used_memory 持续增长,但数据量没有明显增加

# 排查步骤
# 1. 检查是否有 Key 没有设置过期时间
redis-cli DBSIZE
redis-cli INFO keyspace

# 2. 统计有 TTL 和无 TTL 的 Key 比例
python3 << 'EOF'
import redis
r = redis.Redis(decode_responses=True)

cursor = 0
with_ttl = 0
without_ttl = 0

while True:
    cursor, keys = r.scan(cursor, count=100)
    for key in keys:
        if r.ttl(key) >= 0:
            with_ttl += 1
        elif r.ttl(key) == -1:
            without_ttl += 1
    if cursor == 0:
        break

print(f"With TTL: {with_ttl}")
print(f"Without TTL: {without_ttl}")
EOF

# 3. 检查输出缓冲区
redis-cli CLIENT LIST | grep -oP 'omem=\d+' | sort -t= -k2 -nr | head -10
# omem=1048576 → 某个客户端的输出缓冲区占用 1MB

# 4. 检查复制缓冲区
redis-cli INFO replication | grep repl_backlog

问题三:内存使用不均(集群)

# 检查各节点内存使用
for port in 6371 6372 6373; do
    echo "=== Node $port ==="
    redis-cli -p $port INFO memory | grep used_memory_human
done

# 检查 Slot 分布
redis-cli CLUSTER SLOTS

# 检查是否有大 Key 导致分片不均
redis-cli --bigkeys

20.4 持久化问题排查

问题一:RDB 保存失败

# 检查最近一次 BGSAVE 状态
redis-cli INFO persistence | grep rdb_last_bgsave_status
# rdb_last_bgsave_status:err

# 查看日志
tail -100 /var/log/redis/redis-server.log | grep -i "rdb\|save\|error"

# 常见原因
# 1. 磁盘空间不足
df -h /var/lib/redis

# 2. 权限问题
ls -la /var/lib/redis/

# 3. fork 失败(内存不足)
redis-cli INFO memory | grep used_memory_human
free -h
# 确保系统有足够空闲内存(至少等于 Redis 内存占用)

# 4. 内核参数
cat /proc/sys/vm/overcommit_memory
# 应该为 1
sysctl vm.overcommit_memory=1

问题二:AOF 文件损坏

# 症状
# Bad file format reading the append only file

# 修复 AOF 文件
redis-check-aof --fix /var/lib/redis/appendonly.aof

# 验证
redis-check-aof /var/lib/redis/appendonly.aof

问题三:恢复速度慢

# 使用混合持久化(Redis 4.0+)
redis-cli CONFIG SET aof-use-rdb-preamble yes

# 下次 AOF 重写后的文件格式:
# [RDB 快照] + [增量 AOF 命令]
# 加载速度接近纯 RDB

20.5 复制问题排查

问题一:主从同步延迟

# 检查复制状态
redis-cli INFO replication
# master_link_status:up
# master_last_io_seconds_ago:1
# slave_repl_offset:12345
# master_repl_offset:12400

# 计算延迟
# 差值 = master_repl_offset - slave_repl_offset
# 55 字节延迟

# 检查复制积压缓冲区
redis-cli INFO replication | grep repl_backlog
# repl_backlog_active:1
# repl_backlog_size:1048576

# 如果延迟持续增大
# 1. 增大复制积压缓冲区
redis-cli CONFIG SET repl-backlog-size 268435456  # 256MB

# 2. 检查网络质量
ping -c 100 <slave_ip>

# 3. 检查从节点是否在执行慢查询
redis-cli -h <slave_ip> SLOWLOG GET 5

问题二:主从断开

# 症状
redis-cli INFO replication
# master_link_status:down
# master_last_io_seconds_ago:30

# 排查
# 1. 检查主节点是否存活
redis-cli -h <master_ip> PING

# 2. 检查密码
redis-cli CONFIG GET masterauth

# 3. 检查日志
grep -i "replica\|master\|error" /var/log/redis/redis-server.log

20.6 集群问题排查

问题一:集群状态异常

# 检查集群状态
redis-cli CLUSTER INFO
# cluster_state:fail
# cluster_slots_assigned:16384
# cluster_slots_ok:16000
# cluster_slots_pfail:384
# cluster_slots_fail:0

# 查看哪个节点有问题
redis-cli CLUSTER NODES | grep -v connected

# 修复 Slot 分配
redis-cli --cluster fix <node_ip>:<port>

问题二:节点下线

# 查看节点状态
redis-cli CLUSTER NODES

# 尝试重新加入
redis-cli CLUSTER MEET <new_node_ip> <port>

# 忘记已下线节点(15秒后自动)
redis-cli CLUSTER FORGET <node_id>

20.7 生产环境排错清单

问题类别检查命令正常范围
连接状态INFO clientsconnected_clients < maxclients
内存使用INFO memoryused_memory < maxmemory × 80%
碎片率INFO memory1.0 - 1.5
QPSINFO stats根据容量规划
命中率INFO stats> 80%
慢查询SLOWLOG GET无 O(N) 大命令
淘汰数INFO statsevicted_keys = 0
复制状态INFO replicationmaster_link_status = up
fork 耗时INFO statslatest_fork_usec < 500000
持久化INFO persistencelast_bgsave_status = ok

📌 业务场景

场景一:线上延迟突增

# 1. 检查慢查询
redis-cli SLOWLOG GET 10

# 2. 检查大 Key
redis-cli --bigkeys

# 3. 检查 fork 操作
redis-cli INFO stats | grep latest_fork_usec

# 4. 检查内存
redis-cli INFO memory | grep mem_fragmentation_ratio

场景二:内存告警

# 1. 检查内存使用
redis-cli INFO memory

# 2. 查找大 Key
redis-cli --bigkeys

# 3. 清理过期数据
redis-cli DBSIZE

# 4. 调整淘汰策略
redis-cli CONFIG SET maxmemory-policy allkeys-lru

场景三:主从不一致

# 1. 检查复制状态
redis-cli INFO replication

# 2. 手动触发同步
redis-cli -h <slave> REPLICAOF <master> 6379

# 3. 检查复制缓冲区
redis-cli INFO replication | grep repl_backlog

🔗 扩展阅读