如何定位redis阻塞

在 Redis 中定位阻塞原因需要系统性地排查可能导致性能瓶颈的环节。以下是详细的定位步骤和解决方案:


1. 检查 Redis 基础监控指标

(1) 延迟检测

  • 使用 redis-cli 测量延迟

    redis-cli --latency -h <host> -p <port>    # 持续监控延迟
    redis-cli --latency-history -i 5          # 每5秒采样一次
    

    若延迟持续高于 1ms,可能存在阻塞。

  • 通过 INFO 命令查看延迟统计

    redis-cli INFO stats | grep instantaneous_ops_per_sec  # 当前QPS
    redis-cli INFO stats | grep total_commands_processed   # 总命令数
    

(2) 资源使用

  • CPU 和内存
    redis-cli INFO memory | grep used_memory_human      # 内存使用量
    redis-cli INFO cpu | grep used_cpu_sys              # 系统CPU占用
    
  • 网络带宽: 使用 iftopnload 监控 Redis 端口的网络流量。

2. 分析 Redis 日志

(1) 错误日志路径

  • 查看 Redis 配置文件 redis.conf 中的 logfile 路径:
    tail -f /var/log/redis/redis-server.log
    
  • 关键日志线索
    • Background save terminated by signal:持久化失败。
    • OOM command not allowed:内存不足。
    • MISCONF Redis is configured to save RDB snapshots:持久化配置错误。

3. 检查慢查询和大 Key

(1) 慢查询日志

  • 查看慢查询记录
    redis-cli SLOWLOG GET 10  # 获取最近的10条慢查询
    
  • 关注命令类型
    • KEYS *FLUSHALLHGETALL(大 Hash)、ZRANGE(大 ZSet)。
    • 复杂 Lua 脚本(如长时间循环)。

(2) 大 Key 扫描

  • 使用 --bigkeys 扫描
    redis-cli --bigkeys    # 找出大 Key
    
  • 手动检查 Key 大小
    redis-cli MEMORY USAGE <key>   # 查看指定 Key 的内存占用
    

4. 检查持久化操作

(1) RDB/AOF 持久化状态

  • 查看持久化进程
    redis-cli INFO persistence | grep -E "rdb_bgsave_in_progress|aof_rewrite_in_progress"
    
    • rdb_bgsave_in_progress:1 表示 RDB 持久化中。
    • aof_rewrite_in_progress:1 表示 AOF 重写中。

(2) Fork 阻塞问题

  • 日志中检查 fork 耗时
    grep "Background saving terminated" /var/log/redis/redis-server.log
    
    • fork 操作耗时过长(如超过 1s),可能是内存过大或系统配置问题。
  • 优化建议
    • 使用物理机而非虚拟机(减少内存页拷贝开销)。
    • 调整 vm.overcommit_memory=1(允许超额分配内存)。

5. 分析客户端连接

(1) 客户端列表

  • 查看所有客户端连接
    redis-cli CLIENT LIST  # 显示所有连接的客户端信息
    
  • 关注字段
    • idle:连接空闲时间(若大量连接空闲,可能是客户端未释放连接)。
    • cmd:最近执行的命令。
    • name:客户端名称(定位问题客户端)。

(2) 阻塞命令检测

  • 查找阻塞命令
    redis-cli CLIENT LIST | grep flags=B  # 查找阻塞状态的客户端
    
    • 常见阻塞命令:BLPOPBRPOPBRPOPLPUSHSUBSCRIBE

6. 内存与淘汰策略

(1) 内存使用检查

  • 查看内存状态
    redis-cli INFO memory | grep -E "used_memory|maxmemory|mem_fragmentation_ratio"
    
    • mem_fragmentation_ratio > 1.5 表示内存碎片严重。
    • used_memory >= maxmemory 会触发键淘汰(LRU/LFU)。

(2) 键淘汰监控

  • 查看淘汰统计
    redis-cli INFO stats | grep evicted_keys  # 被淘汰的键数量
    
    • evicted_keys 持续增长,需扩容内存或优化数据。

7. 网络与系统级排查

(1) 网络延迟

  • 使用 pingtcpdump
    ping <redis-host>                         # 检查基础网络延迟
    tcpdump -i eth0 port 6379 -w redis.pcap   # 抓包分析网络问题
    

(2) 系统资源限制

  • 检查文件描述符限制
    ulimit -n          # 查看当前限制
    grep "Max open files" /etc/security/limits.conf  # 系统配置
    
    • Redis 需要足够高的文件描述符限制(建议 10032)。

8. 高级工具与调试

(1) 使用 perf 分析性能

  • 生成火焰图
    perf record -p <redis-pid> -g -- sleep 30  # 采样30秒
    perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > redis.svg
    

(2) GDB 调试(谨慎使用)

  • 附加到 Redis 进程
    sudo gdb -p <redis-pid>
    
    • 输入 bt 查看堆栈跟踪(需 Redis 编译时保留调试符号)。

常见阻塞场景与解决方案

阻塞原因 现象 解决方案
慢查询 高延迟,SLOWLOG 中有耗时命令 优化复杂命令,拆分大 Key,使用 SCAN 替代 KEYS
大 Key 操作 单次操作耗时长,内存占用高 拆分 Key(如 Hash 分片),使用 Pipeline 减少网络开销。
持久化 Fork 阻塞 RDB/AOF 重写期间延迟飙升 升级机器内存,关闭 THP(echo never > /sys/kernel/mm/transparent_hugepage/enabled)。
内存不足 OOM 错误,evicted_keys 增加 扩容内存,优化数据结构,设置合理的 maxmemory-policy
客户端阻塞命令 客户端连接堆积,CLIENT LIST 显示阻塞状态 检查客户端代码,避免使用 BLPOP 超时过长,改用非阻塞方案。
网络拥堵 高网络延迟,带宽占满 优化客户端批量操作,升级网络带宽,使用 Redis 集群分散流量。

总结

  1. 监控先行:通过 INFOSLOWLOGCLIENT LIST 快速定位异常点。
  2. 日志分析:检查 Redis 日志中的错误和警告信息。
  3. 资源检查:排查 CPU、内存、网络、文件描述符等系统限制。
  4. 客户端审查:分析客户端行为,避免阻塞命令和连接泄漏。
  5. 工具辅助:使用 perftcpdumpGDB 深入诊断复杂问题。

results matching ""

    No results matching ""