Skip to content

监控与日常运维

redis-cli PING 返回 PONG,监控显示"正常"。但业务侧反馈缓存命中率从 99% 掉到了 80%,接口超时率上升。排查发现 Redis 内存满了在淘汰 key,而监控只检查了 PING

端口能通只说明进程能响应最简单命令。内存淘汰、AOF 写失败、复制延迟、慢命令和 Cluster slot 异常,都可能在 PING 正常返回时发生。

一、INFO 关键字段

INFO 分多个 section,按需查看:

bash
redis-cli INFO server       # 版本、进程、运行时长
redis-cli INFO clients      # 连接数、阻塞数
redis-cli INFO memory       # 内存使用和碎片
redis-cli INFO stats        # 命令、命中率、淘汰
redis-cli INFO persistence  # RDB/AOF 状态
redis-cli INFO replication  # 主从状态和 offset
redis-cli INFO keyspace     # 各 DB 的 key 数和过期情况

各模块的重点字段:

clients

字段含义
connected_clients当前连接数
blocked_clients阻塞等待的客户端数(BLPOP 等),持续高位说明有消费者在等待
rejected_connections因 maxclients 或文件句柄限制被拒绝的连接数,大于 0 要立即排查

memory

字段含义
used_memory_human可读的已用内存
mem_fragmentation_ratio碎片率,长期大于 1.5 说明碎片严重
maxmemory_human内存上限

stats

字段含义
instantaneous_ops_per_sec当前每秒命令数
expired_keys累计过期删除的 key 数
evicted_keys累计因内存满被淘汰的 key 数——和 expired 不同口径(详见 05-过期与内存管理
keyspace_hits / keyspace_misses缓存命中和未命中次数,命中率 = hits / (hits + misses)

命中率突然下降的常见原因:缓存大量集中过期、发布后 key 命名规则变了导致新旧 key 不重合、Redis 数据被清空或切换到了空实例。

persistence:重点关注 rdb_last_bgsave_statusaof_last_write_status,详见 06-持久化-RDB与AOF

replication:重点关注 master_link_status 和主从 offset 差值,详见 08-主从复制

二、慢日志

bash
redis-cli SLOWLOG LEN          # 当前慢日志条数
redis-cli SLOWLOG GET 20       # 最近 20 条

慢日志记录的内容:执行时间(微秒)、命令和参数、客户端地址、时间戳。慢日志只记命令实际执行时间,不包括网络传输和排队等待。

巡检不是看"有没有慢日志"——偶发一条可能是维护操作。同一类命令反复出现在慢日志里(比如某条 HGETALLZRANGE 每次都耗时 > 50ms),才是需要追溯的访问模式或 key 设计问题。

三、持久化

bash
redis-cli INFO persistence | grep -E 'rdb_last_bgsave_status|rdb_last_save_time|rdb_bgsave_in_progress'
redis-cli INFO persistence | grep -E 'aof_enabled|aof_last_write_status|aof_last_bgrewrite_status|aof_current_size'

关注点:

字段异常含义
rdb_last_bgsave_status:err最近一次 BGSAVE 失败——磁盘空间、权限、fork 失败
aof_last_write_status:errAOF 写入失败——同上,但更紧急(影响增量持久化)
aof_current_size 持续增长AOF 重写可能没触发或重写失败
rdb_bgsave_in_progress:1 持续很久快照卡住或实例很大

持久化失败经常和磁盘满、权限错误、fork 失败有关。告警里带上 df -h 的输出和 Redis 日志片段,会比单独一条"持久化失败"更有用。

四、复制

主库:

bash
redis-cli INFO replication | grep -E 'role|connected_slaves|master_repl_offset'

从库:

bash
redis-cli INFO replication | grep -E 'role|master_link_status|master_last_io_seconds_ago|slave_repl_offset'

关注:

异常含义
master_link_status:down从库和主库之间链路断开
master_last_io_seconds_ago 持续增长从库很久没收到主库数据
connected_slaves 少于预期有从库掉线
主从 offset 差距持续扩大从库追不上主库

从库掉线不一定立刻影响主库写入,但影响故障切换能力和备份时效。纯缓存用途的实例对复制延迟可以宽一些;存会话、计数等状态数据的实例要更敏感。

五、Cluster

bash
redis-cli -c CLUSTER INFO
redis-cli -c CLUSTER NODES
redis-cli --cluster check 192.168.10.11:6379

关注:

项目正常标准
cluster_stateok
cluster_slots_assigned16384
cluster_slots_fail0
CLUSTER NODES 中有无 fail 标记
migrating/importing 状态无残留——有残留说明上次 reshard 没完成
主从分布主库和对应从库在不同 IP 上

Cluster 巡检不能只连一个节点。只连一个节点看到正常,不代表没有少数节点处于孤立或故障状态。至少连 2-3 个不同 IP 的节点分别查。

六、Prometheus 监控

redis_exporter 是 Prometheus 生态中常用的 Redis 指标采集器:

bash
redis_exporter \
  --redis.addr redis://127.0.0.1:6379 \
  --redis.password "$REDIS_PASSWORD" \
  --web.listen-address :9121

Prometheus 抓取配置:

yaml
scrape_configs:
  - job_name: redis
    static_configs:
      - targets:
          - 192.168.10.11:9121
          - 192.168.10.129:9121

常用告警指标(具体名称和 redis_exporter 版本有关):

指标告警条件示例
redis_up= 0 表示 exporter 连不上 Redis
redis_memory_used_bytes / redis_memory_max_bytes接近 1 表示内存快满
redis_evicted_keys_total 的增长速率持续增长说明在淘汰数据
redis_connected_clients突然飙升可能是连接泄漏或重试风暴
redis_rdb_last_bgsave_status= 0(失败)
redis_aof_last_write_status= 0(失败)
redis_master_link_status(从库)= 0(断开)
redis_cluster_state(Cluster)= 0(集群不可用)

告警阈值不能直接套用默认值。缓存实例和会话实例对内存、淘汰、复制延迟的容忍度不同——缓存实例 evicted_keys 可能正常,会话实例 evicted_keys 大于 0 就是丢数据。

七、巡检脚本

一个简单的巡检脚本:

bash
#!/bin/bash
set -euo pipefail

host="${1:-127.0.0.1}"
port="${2:-6379}"

cli=(redis-cli -h "$host" -p "$port")

echo "== ping =="
"${cli[@]}" PING

echo "== memory =="
"${cli[@]}" INFO memory | grep -E 'used_memory_human|maxmemory_human|mem_fragmentation_ratio'

echo "== clients =="
"${cli[@]}" INFO clients | grep -E 'connected_clients|blocked_clients'

echo "== persistence =="
"${cli[@]}" INFO persistence | grep -E 'rdb_last_bgsave_status|aof_last_write_status'

echo "== replication =="
"${cli[@]}" INFO replication | grep -E 'role|connected_slaves|master_link_status'

echo "== slowlog =="
"${cli[@]}" SLOWLOG LEN

用数组存 redis-cli 参数是为了避免 host、port 在脚本里到处重复。输出适合人工巡检看;接 Prometheus 时可以用 textfile collector 模式——脚本把关键指标写成 Prometheus 格式的文件,node_exporter 自动采集:

bash
# 在巡检脚本末尾追加,写到 node_exporter 的 textfile 目录
textfile_dir="/var/lib/node_exporter/textfile"
cat > "$textfile_dir/redis_inspection.prom" <<EOF
# HELP redis_memory_used_bytes Redis used memory
# TYPE redis_memory_used_bytes gauge
redis_memory_used_bytes{host="$host",port="$port"} $(redis-cli -h "$host" -p "$port" INFO memory | awk -F: '/^used_memory:/ {print $2}' | tr -d '\r')
# HELP redis_connected_clients Redis connected clients
# TYPE redis_connected_clients gauge
redis_connected_clients{host="$host",port="$port"} $(redis-cli -h "$host" -p "$port" INFO clients | awk -F: '/^connected_clients:/ {print $2}' | tr -d '\r')
EOF

八、备份

备份不只是看文件有没有生成:

bash
ls -lh /backup/redis/
redis-check-rdb /backup/redis/dump-2026-05-22-010000.rdb
检查项确认什么
文件是否存在备份任务是否真的跑了
文件大小是否异常变小(可能只备份了部分数据)
修改时间是否按计划更新(不是几天前的旧文件)
RDB 校验redis-check-rdb 能否正常读取
恢复演练定期拿备份拉起临时 Redis,确认 key 数和关键数据

备份文件存在只是备份链条里的第一环。真正可靠的是定期恢复演练——在临时实例上恢复备份,跑几条业务查询确认数据符合预期。

九、故障处理

连接数升高

bash
redis-cli INFO clients
# 按来源 IP 统计连接分布
redis-cli CLIENT LIST | awk -F'addr=' '{print $2}' | awk -F':' '{print $1}' | sort | uniq -c | sort -nr | head

如果单个 IP 连接数暴涨,看那个 IP 对应的应用是否有连接池泄漏、代码变更后没有释放连接、或者刚重启后瞬时重连风暴。blocked_clients 高则看是否有消费者在 BLPOP 等阻塞命令上长期等待。

内存打满

bash
redis-cli INFO memory | grep -E 'used_memory|maxmemory|evicted_keys'
redis-cli --bigkeys

如果是纯缓存,调整 maxmemory 或淘汰策略;如果 --bigkeys 扫出大集合,考虑拆 key 或用 UNLINK 清理;如果大部分 key 没设 TTL,补过期时间并清理不需要的历史 key。

命中率下降

bash
redis-cli INFO stats | grep -E 'keyspace_hits|keyspace_misses'

先看 evicted_keys 是否在增长——如果是,说明内存不够在踢数据。再看 expired_keys 增长速度——如果集中暴涨,说明大量 key 同时到期。最后看应用日志,确认读写 key 的命名规则是否因发布而改变。

复制断开

bash
redis-cli INFO replication | grep -E 'master_link_status|master_last_io_seconds_ago'

从库侧测试主库端口 nc -vz、确认 masterauth 密码、看主库日志里是否有从库连接和断开的记录。如果从库反复全量同步,查 repl-backlog-size 是否太小或网络是否频繁抖动。

十、运维常见误区

误区一:只监控 PING 就认为 Redis 正常。 PING 只能检测进程是否存活。内存满、持久化失败、复制断开、Cluster slot 异常,都能在 PING 正常时发生。至少要监控:内存使用率、evicted_keys 增长速率、rdb_last_bgsave_statusmaster_link_status(从库)、cluster_state(Cluster)。

误区二:告警阈值直接套默认值。 缓存实例和会话实例对 evicted_keys 的容忍度完全不同——缓存实例 evicted_keys 增长是预期行为,会话实例 evicted_keys > 0 就是丢数据。每个实例的告警阈值要根据它的用途单独设。

误区三:巡检只连一个节点。 Cluster 环境下,只连一个节点看到正常,不代表没有少数节点处于孤立或故障状态。至少连 2-3 个不同 IP 的节点分别查。

误区四:备份文件存在就认为备份成功。 文件存在、大小正常、修改时间是今天——这三样都对,也不代表最近一次 BGSAVE 成功了。rdb_last_bgsave_status 才是判定标准。定期做恢复演练,在临时实例上拉起备份确认 key 数和关键数据,才是真正的"备份验证"。