跳到主要内容

Redis 监控与故障排查

在生产环境中,没有监控的 Redis 是一枚定时炸弹。本章介绍如何实时掌握 Redis 的健康状况,以及在出现问题时如何排查和解决。

核心监控命令 INFO

INFO 是 Redis 最权威的状态输出,包含了内存、连接、CPU 等 10 个分类:

内存信息

127.0.0.1:6379> INFO memory

# 重点指标
used_memory_human: 1.5G # 实际使用内存
used_memory_rss: 2.0G # 操作系统分配给 Redis 的内存(包含碎片)
mem_fragmentation_ratio: 1.33 # 碎片率(建议 1.0~1.5 之间)
maxmemory: 4G # 最大内存限制
maxmemory_policy: allkeys-lru # 淘汰策略

客户端连接信息

127.0.0.1:6379> INFO clients

# 重点指标
connected_clients: 100 # 当前连接数
blocked_clients: 5 # 处于阻塞状态的客户端数(如 BLPOP)
tracking_clients: 0 # 开启客户端缓存的连接数
clients_in_timeout_table: 0 # 在超时表中的客户端数

统计信息

127.0.0.1:6379> INFO stats

# 重点指标
total_connections_received: 10000 # 历史连接总数
total_commands_processed: 1000000 # 历史命令总数
instantaneous_ops_per_sec: 5000 # 每秒处理命令数
total_net_input_bytes: 1GB # 网络输入总字节
total_net_output_bytes: 2GB # 网络输出总字节
keyspace_hits: 800000 # 缓存命中次数
keyspace_misses: 200000 # 缓存未命中次数

复制信息

127.0.0.1:6379> INFO replication

# 重点指标
role: master # 角色
connected_slaves: 2 # 连接的从库数量
slave0: ip=192.168.1.101,port=6379,state=online,offset=12345,lag=0
master_repl_offset: 12345 # 主库复制偏移量

慢查询日志 SLOWLOG

当 Redis 变慢时,首选工具就是 SLOWLOG

配置慢查询日志

# redis.conf
slowlog-log-slower-than 10000 # 超过 10 毫秒记录(微秒单位)
slowlog-max-len 128 # 日志最大容量
# 运行时修改
127.0.0.1:6379> CONFIG SET slowlog-log-slower-than 10000
OK
127.0.0.1:6379> CONFIG SET slowlog-max-len 256
OK

查看慢查询日志

# 获取最新的 10 条慢查询
127.0.0.1:6379> SLOWLOG GET 10

# 输出示例
1) 1) (integer) 1 # 日志 ID
2) (integer) 1609459200 # 时间戳
3) (integer) 15000 # 执行时间(微秒)
4) 1) "KEYS" # 命令
2) "*"
5) "127.0.0.1:54321" # 客户端地址
6) "user1" # 客户端名称

# 获取日志当前长度
127.0.0.1:6379> SLOWLOG LEN
(integer) 5

# 重置日志
127.0.0.1:6379> SLOWLOG RESET
OK

常见慢查询原因

命令问题解决方案
KEYS *阻塞遍历所有键使用 SCAN
HGETALL 大 Hash大键操作拆分键或使用 HSCAN
ZRANGE 大 ZSet大范围查询分批查询
DEL 大键阻塞删除使用 UNLINK

命令监控 MONITOR

MONITOR 可以实时打印服务器接收到的所有请求:

127.0.0.1:6379> MONITOR
OK
1727000000.123 [0 127.0.0.1:5432] "GET" "user:123"
1727000000.234 [0 127.0.0.1:5433] "SET" "counter" "1"
1727000000.345 [0 127.0.0.1:5434] "INCR" "counter"

注意MONITOR 会消耗大量 CPU,仅用于非高负载环境的短时间调试。

延迟追踪 LATENCY

Redis 提供了专门的延迟分析框架。

配置延迟监控

# 设置采样阈值(毫秒)
127.0.0.1:6379> CONFIG SET latency-monitor-threshold 100
OK

查看延迟事件

# 查看最近的延迟事件
127.0.0.1:6379> LATENCY LATEST
1) 1) "command"
2) (integer) 1609459200 # 时间戳
3) (integer) 150 # 延迟(毫秒)
4) (integer) 200 # 最大延迟

# 查看延迟直方图
127.0.0.1:6379> LATENCY GRAPH command

延迟事件类型

事件说明
command命令执行延迟
forkfork 操作延迟
rdb-unlink-temp-fileRDB 临时文件删除延迟
aof-write-pending-fsyncAOF 写入延迟
aof-rewrite-diff-writeAOF 重写差异写入延迟

性能测试 redis-benchmark

内置压测工具,评估当前服务器能抗住多少 QPS。

基本使用

# 测试 100 个并发连接,10 万次请求
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

# 只测试特定的 SET/GET 命令
redis-benchmark -t set,get -q -n 100000

# 测试指定数据大小
redis-benchmark -t set -d 1000 -n 100000

# 使用 Pipeline
redis-benchmark -t set,get -P 10 -n 100000

输出解读

====== SET ======
100000 requests completed in 1.23 seconds
100 parallel clients
3 bytes payload
keep alive: 1

99.95% <= 1 milliseconds
100.00% <= 2 milliseconds
81300.81 requests per second

关键指标:

  • requests per second:每秒请求数(QPS)
  • <= 1 milliseconds:响应时间分布

客户端管理

查看客户端列表

127.0.0.1:6379> CLIENT LIST

# 输出示例
id=1 addr=127.0.0.1:54321 fd=5 name= user=default age=100 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=set

# 字段说明
# id: 客户端 ID
# addr: 客户端地址
# name: 客户端名称
# age: 连接存活时间(秒)
# idle: 空闲时间(秒)
# qbuf: 查询缓冲区大小
# omem: 输出缓冲区内存使用
# cmd: 最后执行的命令

管理客户端

# 设置客户端名称
127.0.0.1:6379> CLIENT SETNAME myapp

# 获取当前客户端信息
127.0.0.1:6379> CLIENT INFO

# 断开指定客户端
127.0.0.1:6379> CLIENT KILL 127.0.0.1:54321

# 断开所有空闲超过 60 秒的客户端
127.0.0.1:6379> CLIENT KILL IDLE 60

生产级监控方案

Prometheus + Grafana

对于中大型系统,建议使用 Redis Exporter + Prometheus + Grafana:

1. 部署 Redis Exporter

# docker-compose.yml
version: '3.8'
services:
redis_exporter:
image: oliver006/redis_exporter:latest
ports:
- "9121:9121"
environment:
- REDIS_ADDR=redis://redis:6379
- REDIS_PASSWORD=your_password

2. Prometheus 配置

# prometheus.yml
scrape_configs:
- job_name: 'redis'
static_configs:
- targets: ['redis_exporter:9121']

3. 核心监控指标

指标说明告警阈值建议
redis_up服务是否存活= 0
redis_connected_clients当前连接数> maxclients * 0.8
redis_memory_used_bytes内存使用量> maxmemory * 0.9
redis_keyspace_hits_total缓存命中次数-
redis_keyspace_misses_total缓存未命中次数-
redis_commands_processed_total命令处理总数-
redis_connected_slaves从库连接数< 预期值

4. 缓存命中率计算

缓存命中率 = keyspace_hits / (keyspace_hits + keyspace_misses)

建议保持在 80% 以上。

监控脚本示例

import redis
import time

def monitor_redis(host='localhost', port=6379, interval=60):
"""Redis 监控脚本"""
r = redis.Redis(host=host, port=port, decode_responses=True)

while True:
try:
# 获取信息
info = r.info()
memory = r.info('memory')
stats = r.info('stats')

# 计算缓存命中率
hits = stats.get('keyspace_hits', 0)
misses = stats.get('keyspace_misses', 0)
hit_rate = hits / (hits + misses) * 100 if (hits + misses) > 0 else 0

# 输出监控数据
print(f"""
========== Redis 监控 ==========
时间: {time.strftime('%Y-%m-%d %H:%M:%S')}
连接数: {info['connected_clients']}
内存使用: {memory['used_memory_human']} / {memory.get('maxmemory_human', 'unlimited')}
碎片率: {memory['mem_fragmentation_ratio']:.2f}
QPS: {stats['instantaneous_ops_per_sec']}
缓存命中率: {hit_rate:.2f}%
Key 数量: {sum(info.get(f'db{i}', {}).get('keys', 0) for i in range(16))}
================================
""")
except Exception as e:
print(f"监控异常: {e}")

time.sleep(interval)

if __name__ == '__main__':
monitor_redis()

故障排查套路

1. 命令变慢

排查步骤

  1. 查看 SLOWLOG 找到慢命令
  2. 检查是否使用 KEYS、大键操作
  3. 检查内存是否达到 maxmemory
  4. 检查是否有大量过期键
# 查看慢查询
SLOWLOG GET 10

# 检查内存
INFO memory

# 检查过期键
INFO keyspace

2. 连接数过多

排查步骤

  1. 查看 INFO clients 确认连接数
  2. 使用 CLIENT LIST 找到异常客户端
  3. 检查应用是否正确使用连接池
# 查看连接数
INFO clients

# 找到空闲连接
CLIENT LIST | grep "idle="

# 断开空闲连接
CLIENT KILL IDLE 60

3. 内存占用过高

排查步骤

  1. 查看 INFO memory 确认内存使用
  2. 使用 redis-cli --bigkeys 查找大键
  3. 检查是否设置了 maxmemory 和淘汰策略
  4. 检查内存碎片率
# 查看内存
INFO memory

# 查找大键
redis-cli --bigkeys

# 查看单个键内存
MEMORY USAGE mykey

4. CPU 使用率过高

排查步骤

  1. 检查是否在执行慢命令
  2. 检查是否有大量请求
  3. 检查是否开启了 MONITOR
# 检查 QPS
INFO stats | grep instantaneous

# 检查是否有 MONITOR
CLIENT LIST | grep monitor

5. 主从同步延迟

排查步骤

  1. 查看 INFO replication 检查 offset
  2. 检查网络延迟
  3. 检查从库负载
# 查看复制信息
INFO replication

# 检查同步偏移量差值
# master_repl_offset 与 slave 的 offset 差值

监控检查清单

每日检查

  • 服务是否正常运行
  • 内存使用率是否正常
  • 连接数是否异常
  • 是否有慢查询告警

每周检查

  • 缓存命中率趋势
  • 大键扫描
  • 持久化状态
  • 主从同步状态

每月检查

  • Redis 版本更新
  • 配置参数优化
  • 容量规划评估
  • 故障演练

小结

本章我们学习了:

  1. INFO 命令:内存、客户端、统计等核心指标
  2. SLOWLOG:慢查询日志配置和查看
  3. MONITOR:实时命令监控
  4. LATENCY:延迟追踪和分析
  5. redis-benchmark:性能测试工具
  6. 客户端管理:查看和管理客户端连接
  7. Prometheus + Grafana:生产级监控方案
  8. 故障排查:常见问题的排查思路

练习

  1. 配置慢查询日志,并分析慢查询原因
  2. 使用 redis-benchmark 测试 Redis 性能
  3. 编写一个 Redis 监控脚本
  4. 模拟一个性能问题并排查解决

参考资料