生产使用的 Redis 健康排查标准操作手册(SOP)

AI摘要
这是一篇关于Redis生产环境故障排查的知识分享,提供了从基础存活检查到连接压力、性能、内存、哨兵架构和网络层的系统性排查流程,并附带了可直接使用的自动化巡检脚本。内容聚焦于技术运维实践,旨在帮助工程师快速定位和解决Redis相关的连接超时与502错误问题。

基于最近遇到的问题:

  • 偶发 connect timeout

  • PHP-FPM 502

  • Sentinel 架构

  • 怀疑 Redis 是否健康

目标只有一个:5分钟内快速判断 Redis 有没有锅


🚨 一、生产排查总流程(值班用)

按这个顺序执行,命中率最高:

① Redis 是否存活
② Redis 是否被打满
③ Redis RT 是否异常
④ Redis 是否拒绝连接
⑤ 是否发生主从/哨兵切换
⑥ 网络/accept 是否异常

下面是每一步的标准命令 + 怎么看 + 异常特征


✅ 二、基础存活检查(30秒)

1️⃣ Ping 探活

redis-cli -a <密码> -h <ip> -p 6379 ping

✅ 正常:

PONG

❌ 异常:

  • timeout

  • NOAUTH

  • LOADING

  • MASTERDOWN

📌 结论:

  • 不通 → 网络或实例问题

  • 通 → 继续往下查


2️⃣ 基础信息快照(必查)

redis-cli -a <密码> info server

重点看:

字段 正常
uptime_in_seconds 持续增长
process_id 存在
tcp_port 正确

⚠️ 如果 uptime 很小:

👉 说明 Redis 刚重启过(很关键)


🚨 三、连接压力排查(最关键)

3️⃣ 当前客户端数量(★★★★★)

redis-cli -a <密码> info clients

重点字段:

connected_clients
blocked_clients
maxclients

🎯 判断标准(生产经验)

connected_clients 风险
< 2000 ✅ 安全
2000–5000 ⚠️ 注意
5000–8000 🚨 危险
>80% maxclients 💥 高危

⚠️ 必看拒绝连接

同一输出里找:

rejected_connections

🚨 如果 > 0:

👉 实锤 Redis 被打满过

这是 connect timeout 的头号元凶。


🚨 四、性能/RT 排查(是否 Redis 变慢)

4️⃣ QPS 与事件循环

redis-cli -a <密码> info stats

重点看:

instantaneous_ops_per_sec
latest_fork_usec
eventloop_duration_usec

🎯 异常特征

❌ Redis 卡顿典型

如果看到:

  • ops 很高(几万+)

  • eventloop_duration 很大

  • latest_fork_usec 很大(>100ms)

👉 Redis 可能在抖


5️⃣ 慢日志(★★★★★ 必查)

redis-cli -a <密码> slowlog len
redis-cli -a <密码> slowlog get 10

🎯 判断标准

slowlog len 结论
0 ✅ 很健康
1–50 ⚠️ 观察
>100 🚨 有慢查询
持续增长 💥 Redis 被拖慢

🚨 五、内存与淘汰(避免隐形风险)

6️⃣ 内存状态

redis-cli -a <密码> info memory

重点看:

used_memory_human
maxmemory
evicted_keys

❌ 危险信号

如果:

  • evicted_keys 持续增长

  • 内存接近 maxmemory

👉 Redis 会抖动甚至阻塞


🚨 六、连接层 / TCP 排查(专治偶发 timeout)

这一步是你这种情况非常关键


7️⃣ 查看 Redis 日志(★★★★★)

Linux:

grep -i "accept" redis.log
grep -i "client" redis.log
grep -i "error" redis.log

🚨 命中即实锤

如果看到:

accept() failed
Error accepting a client connection
max number of clients reached

👉 100% 连接层问题


🚨 七、Sentinel 排查(哨兵架构必查)

你现在最该重点盯这个。


8️⃣ Sentinel 主节点状态

redis-cli -p 26381 sentinel masters

看:

  • flags

  • ip/port

  • role


🚨 Sentinel 日志(★★★★★)

docker logs sentinel-1 | egrep -i "sdown|odown|switch-master|failover"

❌ 如果出现

+sdown
+odown
+switch-master
+failover

👉 哨兵切主导致连接抖动(高概率根因)


🚨 八、网络层快速排查(高级)

如果上面都正常,再看这个。


9️⃣ 查看 TCP 队列

在 Redis 机器:

ss -lnt | grep 6379

看:

  • Send-Q

  • Recv-Q

如果 Recv-Q 很大:

👉 accept backlog 满了
👉 会导致 connect timeout



🧭 九、给你一个生产快速判断口诀(值班神器)

遇到 Redis 502,按这个心法:

先看连,再看慢,再看拒,最后看哨兵

展开就是:

1️⃣ 看 connected_clients
2️⃣ 看 rejected_connections
3️⃣ 看 slowlog
4️⃣ 看 Redis 日志 accept
5️⃣ 看 sentinel 是否切主

基本 95% 的 Redis 事故都能定位。


附加巡检脚本:


🚀 使用方式

保存为:

redis_health_check.sh

赋权:

chmod +x redis_health_check.sh

执行:

./redis_health_check.sh 127.0.0.1 6379 123456

如果有 Sentinel:

./redis_health_check.sh 127.0.0.1 6379 123456 127.0.0.1 26381

✅ 生产版巡检脚本(可直接用)

#!/usr/bin/env bash

# ============================================
# Redis + Sentinel 生产健康巡检脚本
# Author: ChatGPT SRE Edition
# ============================================

REDIS_HOST=${1:-127.0.0.1}
REDIS_PORT=${2:-6379}
REDIS_PASS=${3:-""}

SENTINEL_HOST=${4:-""}
SENTINEL_PORT=${5:-26379}

REDIS_CLI="redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT}"
[ -n "$REDIS_PASS" ] && REDIS_CLI="$REDIS_CLI -a ${REDIS_PASS}"

echo "======================================"
echo " Redis Health Check @ $(date '+%F %T')"
echo "======================================"
echo

score=100

# ================================
# 1. PING 检查
# ================================
echo "[1] PING 检查"
pong=$($REDIS_CLI ping 2>/dev/null)

if [[ "$pong" == "PONG" ]]; then
    echo "✅ Redis 存活"
else
    echo "❌ Redis 无响应"
    score=$((score-50))
fi
echo

# ================================
# 2. 客户端连接数
# ================================
echo "[2] 客户端连接检查"

clients_info=$($REDIS_CLI info clients 2>/dev/null)

connected=$(echo "$clients_info" | grep connected_clients | cut -d: -f2 | tr -d '\r')
rejected=$(echo "$clients_info" | grep rejected_connections | cut -d: -f2 | tr -d '\r')
maxclients=$($REDIS_CLI config get maxclients 2>/dev/null | tail -1)

echo "connected_clients = $connected"
echo "maxclients        = $maxclients"
echo "rejected_conn     = $rejected"

usage_pct=$((connected*100/maxclients))

if (( usage_pct > 80 )); then
    echo "🚨 客户端连接接近上限"
    score=$((score-20))
elif (( usage_pct > 50 )); then
    echo "⚠️ 客户端连接较高"
    score=$((score-10))
else
    echo "✅ 客户端连接正常"
fi

if (( rejected > 0 )); then
    echo "🚨 存在被拒绝连接"
    score=$((score-30))
fi
echo

# ================================
# 3. 性能检查
# ================================
echo "[3] 性能检查"

stats=$($REDIS_CLI info stats 2>/dev/null)

ops=$(echo "$stats" | grep instantaneous_ops_per_sec | cut -d: -f2 | tr -d '\r')
eventloop=$(echo "$stats" | grep instantaneous_eventloop_duration_usec | cut -d: -f2 | tr -d '\r')

echo "ops_per_sec       = $ops"
echo "eventloop_usec    = $eventloop"

if (( eventloop > 5000 )); then
    echo "🚨 Redis 事件循环延迟较高"
    score=$((score-20))
else
    echo "✅ Redis RT 正常"
fi
echo

# ================================
# 4. 慢日志检查
# ================================
echo "[4] 慢日志检查"

slowlen=$($REDIS_CLI slowlog len 2>/dev/null)

echo "slowlog_len       = $slowlen"

if (( slowlen > 100 )); then
    echo "🚨 慢查询堆积"
    score=$((score-20))
elif (( slowlen > 0 )); then
    echo "⚠️ 存在慢查询"
    score=$((score-5))
else
    echo "✅ 无慢查询"
fi
echo

# ================================
# 5. 内存检查
# ================================
echo "[5] 内存检查"

meminfo=$($REDIS_CLI info memory 2>/dev/null)
evicted=$(echo "$meminfo" | grep evicted_keys | cut -d: -f2 | tr -d '\r')

echo "evicted_keys      = $evicted"

if (( evicted > 0 )); then
    echo "🚨 出现内存淘汰"
    score=$((score-15))
else
    echo "✅ 内存状态健康"
fi
echo

# ================================
# 6. Sentinel 检查(可选)
# ================================
if [[ -n "$SENTINEL_HOST" ]]; then
    echo "[6] Sentinel 检查"

    SENTINEL_CLI="redis-cli -h ${SENTINEL_HOST} -p ${SENTINEL_PORT}"
    masters=$($SENTINEL_CLI sentinel masters 2>/dev/null)

    if [[ -z "$masters" ]]; then
        echo "❌ Sentinel 无法获取 master"
        score=$((score-30))
    else
        echo "✅ Sentinel 正常"
    fi
    echo
fi

# ================================
# 总评分
# ================================
echo "======================================"
echo "健康评分: $score / 100"

if (( score >= 90 )); then
    echo "🟢 状态: 健康"
elif (( score >= 70 )); then
    echo "🟡 状态: 需关注"
else
    echo "🔴 状态: 存在风险"
fi

echo "======================================"

🎯 这版脚本能帮你抓什么问题

它专门覆盖你现在最可能的坑:

  • Redis 是否存活

  • 是否连接打满

  • 是否被拒绝连接

  • 是否 RT 抖动

  • 是否慢查询

  • 是否内存淘汰

  • Sentinel 是否异常

基本覆盖 95% 生产事故


🚀(强烈推荐)生产增强用法

建议加 crontab:

*/5 * * * * /path/redis_health_check.sh >> /var/log/redis_health.log

你就拥有:

✅ 持续健康记录
✅ 可追溯
✅ 出事可回放


本作品采用《CC 协议》,转载必须注明作者和本文链接
每天一点小知识,到那都是大佬,哈哈
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!