背景與目的
Redis作為高性能內(nèi)存數(shù)據(jù)庫(kù),廣泛應(yīng)用于緩存、會(huì)話存儲(chǔ)、消息隊(duì)列等場(chǎng)景。對(duì)Redis運(yùn)行狀況的有效監(jiān)控,是保障業(yè)務(wù)穩(wěn)定性的關(guān)鍵。本文的目的是幫助運(yùn)維工程師建立完整的Redis監(jiān)控知識(shí)體系,講解需要監(jiān)控哪些指標(biāo)、如何采集這些指標(biāo)、以及如何設(shè)置合理的告警閾值。
前置知識(shí):本文假設(shè)你具備基本的Linux操作能力,了解Redis的基本概念和常用命令,有過(guò)Redis實(shí)際維護(hù)經(jīng)驗(yàn)。
環(huán)境說(shuō)明:本文基于Redis 7.4.x,Prometheus 2.50.x,Grafana 11.x。
1. Redis監(jiān)控的重要性
1.1 監(jiān)控不足的常見(jiàn)問(wèn)題
性能問(wèn)題:
內(nèi)存接近上限,淘汰策略生效導(dǎo)致命中率下降
CPU單核瓶頸,請(qǐng)求處理變慢
網(wǎng)絡(luò)帶寬打滿,請(qǐng)求超時(shí)
可用性問(wèn)題:
主從復(fù)制中斷,數(shù)據(jù)不一致
持久化失敗,數(shù)據(jù)丟失風(fēng)險(xiǎn)
客戶端連接耗盡,新請(qǐng)求被拒絕
容量問(wèn)題:
內(nèi)存規(guī)劃不足,無(wú)法承載數(shù)據(jù)增長(zhǎng)
bigkey導(dǎo)致內(nèi)存分配失敗
鍵數(shù)量接近上限(內(nèi)存碎片)
1.2 監(jiān)控體系架構(gòu)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 應(yīng)用層 │────│ Redis │────│ 監(jiān)控層 │
│ (業(yè)務(wù)代碼) │ │ (被監(jiān)控) │ │ (采集/存儲(chǔ))│
└─────────────┘ └─────────────┘ └─────────────┘
│ │
│ ▼
│ ┌─────────────┐
└───────────│ 告警層 │
│ (Alertmanager)│
└─────────────┘
2. 基礎(chǔ)運(yùn)行指標(biāo)
2.1 版本和進(jìn)程信息
# 查看Redis版本 redis-cli INFO server | grep redis_version # redis_version: 7.4.0 # redis_mode: standalone # os: Linux 6.8.5 x86_64 # arch_bits: 64 # process_id: 12345 # tcp_port: 6379
2.2 uptime指標(biāo)
# 查看運(yùn)行時(shí)長(zhǎng)
redis-cli INFO server | grep uptime_in
# uptime_in_seconds: 864000
# uptime_in_days: 10
# 監(jiān)控腳本
#!/bin/bash
uptime_seconds=$(redis-cli INFO server | grep uptime_in_seconds | cut -d: -f2)
uptime_days=$(echo"scale=2;$uptime_seconds/86400"| bc)
echo"Redis運(yùn)行時(shí)間:${uptime_days}天"
# 如果uptime過(guò)短(比如<1小時(shí)),可能是剛重啟,需要告警
2.3 基礎(chǔ)健康檢查腳本
#!/bin/bash # script: redis_health_check.sh # 用途:Redis基礎(chǔ)健康檢查 echo"=== Redis健康檢查 ===" # 1. 檢查進(jìn)程是否存活 ifredis-cli PING 2>/dev/null | grep -q PONG;then echo"? Redis進(jìn)程存活" else echo"? Redis進(jìn)程不可用" exit1 fi # 2. 檢查版本 VERSION=$(redis-cli INFO server | grep redis_version | cut -d: -f2 | tr -d' ') echo"? 版本:$VERSION" # 3. 檢查運(yùn)行時(shí)間 UPTIME=$(redis-cli INFO server | grep uptime_in_days | cut -d: -f2 | tr -d' ') echo"? 運(yùn)行天數(shù):${UPTIME}天" # 4. 檢查是否可寫(xiě) ifredis-cli SET test_key test_value EX 10 > /dev/null;then redis-cli DEL test_key > /dev/null echo"? 可寫(xiě)" else echo"? 不可寫(xiě)(可能內(nèi)存已滿)" fi # 5. 檢查復(fù)制狀態(tài) ROLE=$(redis-cli INFO replication | grep role: | cut -d: -f2 | tr -d' ') echo"? 角色:$ROLE"
3. 內(nèi)存指標(biāo)詳解
3.1 核心內(nèi)存指標(biāo)
redis-cli INFO memory # used_memory: 104857600 # Redis申請(qǐng)的總內(nèi)存(字節(jié)) # used_memory_human: 100.00M # 人類可讀格式 # used_memory_rss: 115673600 # 操作系統(tǒng)報(bào)告的物理內(nèi)存占用 # used_memory_rss_human: 110.32M # used_memory_peak: 209715200 # 歷史峰值 # used_memory_peak_human: 200.00M # used_memory_peak_perc: 100.00% # 使用率百分比 # used_memory_lua: 33792 # Lua引擎內(nèi)存 # used_memory_lua_human: 33.00K # maxmemory: 1073741824 # 配置的最大內(nèi)存 # maxmemory_human: 1.00G # maxmemory_policy: allkeys-lru # 淘汰策略 # memory_frag_ratio: 1.10 # 內(nèi)存碎片率 # memory_frag_bytes:10737418 # 碎片字節(jié)數(shù)
3.2 內(nèi)存告警腳本
#!/bin/bash
# script: redis_memory_alert.sh
# 用途:Redis內(nèi)存告警檢查
WARNING_THRESHOLD=80
CRITICAL_THRESHOLD=90
INFO=$(redis-cli INFO memory)
USED=$(echo"$INFO"| grep"^used_memory:"| cut -d: -f2 | tr -d'
')
MAX=$(echo"$INFO"| grep"^maxmemory:"| cut -d: -f2 | tr -d'
')
RSS=$(echo"$INFO"| grep"^used_memory_rss:"| cut -d: -f2 | tr -d'
')
FRAG=$(echo"$INFO"| grep"^mem_fragment_ratio:"| cut -d: -f2 | tr -d'
')
# 計(jì)算使用率
if["$MAX"!="0"];then
USAGE=$(echo"scale=2;$USED* 100 /$MAX"| bc)
echo"內(nèi)存使用率:${USAGE}%"
echo"已使用:$(echo "scale=2; $USED/1024/1024" | bc)MB"
echo"最大限制:$(echo "scale=2; $MAX/1024/1024" | bc)MB"
echo"物理占用:$(echo "scale=2; $RSS/1024/1024" | bc)MB"
echo"碎片率:$FRAG"
# 告警判斷
USAGE_INT=$(echo"$USAGE"| cut -d. -f1)
if["$USAGE_INT"-ge"$CRITICAL_THRESHOLD"];then
echo"ALERT: 內(nèi)存使用率${USAGE}%,超過(guò)${CRITICAL_THRESHOLD}%,請(qǐng)立即處理!"
# 發(fā)送告警
elif["$USAGE_INT"-ge"$WARNING_THRESHOLD"];then
echo"WARNING: 內(nèi)存使用率${USAGE}%,超過(guò)${WARNING_THRESHOLD}%"
fi
else
echo"maxmemory未設(shè)置"
fi
3.3 內(nèi)存指標(biāo)詳細(xì)說(shuō)明
| 指標(biāo) | 說(shuō)明 | 正常范圍 | 異常處理 |
|---|---|---|---|
| used_memory | Redis申請(qǐng)的內(nèi)存 | - | - |
| used_memory_rss | 物理內(nèi)存占用 | - | - |
| mem_fragment_ratio | 碎片率 | 1.0-1.5 | >2.0需優(yōu)化 |
| maxmemory | 配置的最大內(nèi)存 | - | - |
| mem_not_counted_for_evict | 淘汰時(shí)不計(jì)入的內(nèi)存 | - | - |
4. 持久化指標(biāo)
4.1 RDB持久化
redis-cli INFO persistence # rdb_changes_since_last_save: 0 # 距上次保存后的變化次數(shù) # rdb_bgsave_in_progress: 0 # bgsave是否進(jìn)行中 # rdb_last_save_time: 1743619200 # 上次保存的Unix時(shí)間戳 # rdb_last_bgsave_status: ok # 上次bgsave狀態(tài) # rdb_last_bgsave_time_sec: -1 # 上次bgsave耗時(shí)(秒) # rdb_current_bgsave_time_sec: -1 # 當(dāng)前bgsave已執(zhí)行時(shí)間 # rdb_saves: 100 # 累計(jì)保存次數(shù)
4.2 AOF持久化
redis-cli INFO persistence # aof_enabled: 1 # AOF是否啟用 # aof_rewrite_in_progress: 0 # AOF重寫(xiě)是否進(jìn)行中 # aof_rewrite_scheduled: 0 # 是否計(jì)劃AOF重寫(xiě) # aof_last_rewrite_time_sec: -1 # 上次AOF重寫(xiě)耗時(shí) # aof_current_rewrite_time_sec: -1 # 當(dāng)前AOF重寫(xiě)已執(zhí)行時(shí)間 # aof_last_bgrewrite_status: ok # 上次AOF重寫(xiě)狀態(tài) # aof_last_write_status: ok # 上次AOF寫(xiě)入狀態(tài) # aof_delayed_fsync: 0 # 延遲fsync次數(shù)
4.3 持久化監(jiān)控腳本
#!/bin/bash
# script: redis_persistence_check.sh
# 用途:檢查持久化健康狀態(tài)
echo"=== Redis持久化檢查 ==="
INFO=$(redis-cli INFO persistence)
# RDB檢查
rdb_status=$(echo"$INFO"| grep"^rdb_last_bgsave_status:"| cut -d: -f2 | tr -d'
')
rdb_in_progress=$(echo"$INFO"| grep"^rdb_bgsave_in_progress:"| cut -d: -f2 | tr -d'
')
rdb_time=$(echo"$INFO"| grep"^rdb_last_bgsave_time_sec:"| cut -d: -f2 | tr -d'
')
echo"RDB狀態(tài):"
echo" 上次保存狀態(tài):$rdb_status"
echo" 保存中:$rdb_in_progress"
if["$rdb_time"!="-1"];then
echo" 耗時(shí):${rdb_time}秒"
fi
# AOF檢查
aof_enabled=$(echo"$INFO"| grep"^aof_enabled:"| cut -d: -f2 | tr -d'
')
aof_status=$(echo"$INFO"| grep"^aof_last_write_status:"| cut -d: -f2 | tr -d'
')
echo"AOF狀態(tài):"
echo" 啟用:$aof_enabled"
echo" 上次寫(xiě)入狀態(tài):$aof_status"
# 檢查異常
if["$rdb_status"!="ok"];then
echo" RDB保存失??!"
fi
if["$aof_status"!="ok"];then
echo" AOF寫(xiě)入失??!"
fi
5. 主從復(fù)制指標(biāo)
5.1 復(fù)制狀態(tài)查看
# 主節(jié)點(diǎn) redis-cli INFO replication # role: master # connected_slaves: 2 # slave0:ip=192.168.1.101,port=6379,state=online,offset=123456 # slave1:ip=192.168.1.102,port=6379,state=online,offset=123456 # master_repl_offset: 123456 # 從節(jié)點(diǎn) redis-cli INFO replication # role: slave # master_host: 192.168.1.100 # master_port: 6379 # master_link_status: up # master_repl_offset: 123456 # slave_repl_offset: 123456
5.2 復(fù)制延遲
#!/bin/bash # script: check_replication_lag.sh # 用途:檢查主從復(fù)制延遲 INFO=$(redis-cli INFO replication) echo"=== 復(fù)制狀態(tài)檢查 ===" role=$(echo"$INFO"| grep"^role:"| cut -d: -f2 | tr -d' ') if["$role"="master"];then echo"角色:主節(jié)點(diǎn)" slaves=$(echo"$INFO"| grep"^slave"| wc -l) echo"從節(jié)點(diǎn)數(shù)量:$slaves" # 檢查每個(gè)從節(jié)點(diǎn)的延遲 echo"$INFO"| grep"^slave"|whileIFS=,read-ra slave;do echo" ${slave[0]}" done elif["$role"="slave"];then echo"角色:從節(jié)點(diǎn)" master=$(echo"$INFO"| grep"^master_host:"| cut -d: -f2 | tr -d' ') link_status=$(echo"$INFO"| grep"^master_link_status:"| cut -d: -f2 | tr -d' ') echo"主節(jié)點(diǎn):$master" echo"連接狀態(tài):$link_status" if["$link_status"!="up"];then echo" 主從連接中斷!" fi fi
5.3 復(fù)制相關(guān)指標(biāo)說(shuō)明
| 指標(biāo) | 說(shuō)明 | 正常值 | 告警閾值 |
|---|---|---|---|
| connected_slaves | 連接的從節(jié)點(diǎn)數(shù) | - | 與預(yù)期不符 |
| master_link_status | 主從連接狀態(tài) | up | down |
| slave_repl_offset | 從節(jié)點(diǎn)復(fù)制偏移量 | - | 與主節(jié)點(diǎn)差異大 |
| master_repl_offset | 主節(jié)點(diǎn)復(fù)制偏移量 | - | - |
| replication_lag | 復(fù)制延遲(秒) | 0 | >10秒 |
6. 客戶端連接指標(biāo)
6.1 連接統(tǒng)計(jì)
redis-cli INFO clients # connected_clients: 50 # 當(dāng)前連接的客戶端數(shù) # cluster_connections: 0 # 集群連接數(shù) # maxclients: 10000 # 最大客戶端數(shù)限制 # blocked_clients: 0 # 阻塞中的客戶端數(shù)(BLPOP等) # tracking_clients: 0 # 客戶端追蹤數(shù)
6.2 客戶端列表
# 查看所有客戶端 redis-cli CLIENT LIST # 輸出格式: # id=1 addr=192.168.1.100:12345 fd=8 name= age=100 idle=0 flags=N db=0 sub=0 pub=0 multi=-1 cmd=ping # 字段說(shuō)明: # id: 客戶端ID # addr: IP和端口 # fd: 文件描述符 # idle: 空閑時(shí)間(秒) # flags: 客戶端類型(N=普通,M=master,S=slave) # cmd: 最近執(zhí)行的命令
6.3 連接監(jiān)控腳本
#!/bin/bash
# script: redis_clients_check.sh
# 用途:檢查客戶端連接狀態(tài)
echo"=== Redis客戶端檢查 ==="
INFO=$(redis-cli INFO clients)
CLIENTS=$(echo"$INFO"| grep"^connected_clients:"| cut -d: -f2 | tr -d'
')
MAX=$(echo"$INFO"| grep"^maxclients:"| cut -d: -f2 | tr -d'
')
BLOCKED=$(echo"$INFO"| grep"^blocked_clients:"| cut -d: -f2 | tr -d'
')
echo"當(dāng)前連接數(shù):$CLIENTS"
echo"最大限制:$MAX"
echo"阻塞客戶端:$BLOCKED"
# 計(jì)算使用率
if["$MAX"!="0"];then
USAGE=$(echo"scale=2;$CLIENTS* 100 /$MAX"| bc)
echo"連接使用率:${USAGE}%"
# 告警閾值
if(( $(echo"$USAGE> 80"| bc -l) ));then
echo" 連接數(shù)接近上限!"
fi
fi
# 查找空閑連接
echo""
echo"空閑超過(guò)1小時(shí)的連接:"
redis-cli CLIENT LIST | awk -F'[,=]''$5>3600 {print $2, $5"秒"}'
6.4 連接異常檢測(cè)
#!/bin/bash
# script: detect_client_issues.sh
# 用途:檢測(cè)客戶端連接異常
echo"=== 客戶端異常檢測(cè) ==="
# 1. 檢測(cè)長(zhǎng)期空閑連接
echo"【1】空閑連接(>1小時(shí)):"
redis-cli CLIENT LIST |whileIFS=,read-ra fields;do
idle=$(echo"${fields[@]}"| grep -oP'idle=Kd+')
if[ -n"$idle"] && ["$idle"-gt 3600 ];then
addr=$(echo"${fields[@]}"| grep -oP'addr=K[w.:]+')
echo" $addridle=${idle}s"
fi
done
# 2. 檢測(cè)異常IP連接
echo""
echo"【2】連接數(shù)最多的IP:"
redis-cli CLIENT LIST | awk -F'[=, ]''{print $4}'| sort | uniq -c | sort -rn | head -5
# 3. 殺掉空閑連接
read-p"是否關(guān)閉空閑超過(guò)6小時(shí)的連接?(y/N): "confirm
if["$confirm"="y"];then
redis-cli CLIENT LIST |whileIFS=,read-ra fields;do
idle=$(echo"${fields[@]}"| grep -oP'idle=Kd+')
id=$(echo"${fields[@]}"| grep -oP'^id=Kd+')
if[ -n"$idle"] && ["$idle"-gt 21600 ];then
echo"關(guān)閉連接:$id(idle=${idle}s)"
redis-cli CLIENT KILL ID"$id"
fi
done
fi
7. 鍵空間統(tǒng)計(jì)
7.1 keyspace信息
redis-cli INFO keyspace # db0:keys=1000000,expires=500000,avg_ttl=3600000000 # db1:keys=0,expires=0,avg_ttl=0 # 字段說(shuō)明: # keys: 鍵數(shù)量 # expires: 有過(guò)期時(shí)間的鍵數(shù)量 # avg_ttl: 平均TTL(納秒)
7.2 鍵統(tǒng)計(jì)腳本
#!/bin/bash # script: redis_keyspace_stats.sh # 用途:鍵空間統(tǒng)計(jì)分析 echo"=== Redis鍵空間統(tǒng)計(jì) ===" # 查看每個(gè)數(shù)據(jù)庫(kù) redis-cli INFO keyspace echo"" # 鍵數(shù)量變化趨勢(shì) echo"【鍵數(shù)量歷史記錄】" if[ -f /tmp/redis_keys_history.txt ];then tail -20 /tmp/redis_keys_history.txt else echo"無(wú)歷史記錄" fi # 記錄當(dāng)前數(shù)據(jù) DBINFO=$(redis-cli INFO keyspace | grep"^db0:") KEYS=$(echo"$DBINFO"| cut -d: -f2 | cut -d, -f1 | cut -d= -f2) DATE=$(date +%Y-%m-%d %H:%M:%S) echo"$DATE$KEYS">> /tmp/redis_keys_history.txt # 計(jì)算增長(zhǎng)率 if[ -f /tmp/redis_keys_prev.txt ];then PREV=$(cat /tmp/redis_keys_prev.txt) PREV_KEYS=$(echo"$PREV"| awk'{print $2}') PREV_TIME=$(echo"$PREV"| awk'{print $1}') PREV_TS=$(date -d"$PREV_TIME"+%s 2>/dev/null ||echo"0") CUR_TS=$(date +%s) DIFF=$((KEYS - PREV_KEYS)) TIME_DIFF=$((CUR_TS - PREV_TS)) if["$TIME_DIFF"-gt 0 ];then RATE=$(echo"scale=2;$DIFF/$TIME_DIFF"| bc) echo"鍵增長(zhǎng)率:$RATE鍵/秒" fi fi echo"$DATE$KEYS"> /tmp/redis_keys_prev.txt # 大鍵統(tǒng)計(jì) echo"" echo"【鍵大小分布】" redis-cli --scan --pattern'*'| head -1000 |whilereadkey;do type=$(redis-cli TYPE"$key"2>/dev/null) if["$type"="string"];then len=$(redis-cli STRLEN"$key"2>/dev/null) elif["$type"="list"];then len=$(redis-cli LLEN"$key"2>/dev/null) elif["$type"="set"];then len=$(redis-cli SCARD"$key"2>/dev/null) elif["$type"="zset"];then len=$(redis-cli ZCARD"$key"2>/dev/null) elif["$type"="hash"];then len=$(redis-cli HLEN"$key"2>/dev/null) fi echo"$key|$type|$len" done| awk -F'|''{print $2,$3}'| sort | uniq -c | sort -rn | head -10
8. 命令統(tǒng)計(jì)
8.1 commandstats
redis-cli INFO commandstats # cmdstat_get:calls=1000000,usec=5000000,usec_per_call=5.00 # cmdstat_set:calls=500000,usec=3000000,usec_per_call=6.00 # cmdstat_del:calls=100000,usec=1000000,usec_per_call=10.00
8.2 慢命令分析
#!/bin/bash
# script: analyze_slow_commands.sh
# 用途:分析執(zhí)行最慢的命令
echo"=== 慢命令分析 ==="
redis-cli INFO commandstats | grep"^cmdstat"|whileIFS=:read-ra line;do
cmd=${line[0]#cmdstat_}
stats=${line[1]}
calls=$(echo"$stats"| grep -oP'calls=Kd+')
usec=$(echo"$stats"| grep -oP'usec=Kd+')
if[ -n"$calls"] && [ -n"$usec"];then
avg_usec=$(echo"scale=2;$usec/$calls"| bc)
echo"$cmd:$calls次, 平均${avg_usec}微秒"
fi
done| sort -t: -k4 -rn | head -10
9. 吞吐指標(biāo)
9.1 QPS計(jì)算
# 查看統(tǒng)計(jì)數(shù)據(jù) redis-cli INFO stats # instantaneous_ops_per_sec: 5000 # 每秒操作數(shù) # total_commands_processed: 10000000 # 累計(jì)處理命令數(shù) # rejected_commands: 0 # 被拒絕的命令數(shù)
9.2 QPS監(jiān)控腳本
#!/bin/bash # script: redis_qps_monitor.sh # 用途:監(jiān)控Redis QPS echo"=== Redis QPS監(jiān)控 ===" INFO=$(redis-cli INFO stats) OPS=$(echo"$INFO"| grep"^instantaneous_ops_per_sec:"| cut -d: -f2 | tr -d' ') TOTAL=$(echo"$INFO"| grep"^total_commands_processed:"| cut -d: -f2 | tr -d' ') REJECTED=$(echo"$INFO"| grep"^rejected_commands:"| cut -d: -f2 | tr -d' ') CONNECTIONS=$(echo"$INFO"| grep"^total_connections_received:"| cut -d: -f2 | tr -d' ') echo"當(dāng)前QPS:$OPS" echo"累計(jì)處理命令:$TOTAL" echo"被拒絕命令:$REJECTED" echo"累計(jì)連接數(shù):$CONNECTIONS" # 記錄QPS歷史 echo"$(date +%Y-%m-%d %H:%M:%S)$OPS">> /tmp/redis_qps_history.txt # 計(jì)算平均QPS if[ -f /tmp/redis_qps_history.txt ];then echo"" echo"【QPS趨勢(shì)(最近10分鐘)】" tail -10 /tmp/redis_qps_history.txt fi
9.3 延遲監(jiān)控
#!/bin/bash
# script: redis_latency_monitor.sh
# 用途:監(jiān)控Redis延遲
echo"=== Redis延遲監(jiān)控 ==="
# 基準(zhǔn)延遲測(cè)試
echo"【Redis延遲基準(zhǔn)測(cè)試】"
foriin{1..5};do
start=$(date +%s%N)
redis-cli PING > /dev/null
end=$(date +%s%N)
latency=$(( (end - start) / 1000000 ))
echo" 測(cè)試$i:${latency}ms"
done
# 使用redis-cli內(nèi)置延遲測(cè)試
ifcommand-v redis-cli &> /dev/null;then
echo""
echo"【延遲分布】"
redis-cli --latency-history
fi
10. Sentinel/Cluster狀態(tài)
10.1 Redis Sentinel監(jiān)控
# 查看Sentinel狀態(tài) redis-cli SENTINEL masters # 查看特定master redis-cli SENTINEL master mymaster # 查看從節(jié)點(diǎn) redis-cli SENTINEL slaves mymaster # 查看Sentinel實(shí)例 redis-cli SENTINEL sentinels mymaster
10.2 Sentinel監(jiān)控腳本
#!/bin/bash
# script: redis_sentinel_monitor.sh
# 用途:監(jiān)控Redis Sentinel狀態(tài)
echo"=== Redis Sentinel監(jiān)控 ==="
MASTER_NAME="mymaster"
# 獲取主節(jié)點(diǎn)信息
MASTER=$(redis-cli SENTINEL get-master-addr-by-name"$MASTER_NAME")
echo"主節(jié)點(diǎn):$MASTER"
# 檢查主節(jié)點(diǎn)狀態(tài)
MASTER_STATUS=$(redis-cli SENTINEL master"$MASTER_NAME"| grep -E"^status$"| awk'{print $2}')
echo"主節(jié)點(diǎn)狀態(tài):$MASTER_STATUS"
# 獲取從節(jié)點(diǎn)列表
echo""
echo"從節(jié)點(diǎn):"
redis-cli SENTINEL slaves"$MASTER_NAME"|whilereadline;do
echo" $line"
done
# 檢查主觀下線
SDOWN=$(redis-cli SENTINEL masters | grep -A1"name"| head -2)
echo""
echo"主觀下線狀態(tài):$SDOWN"
10.3 Redis Cluster狀態(tài)
# 查看集群狀態(tài) redis-cli cluster info # 輸出: # cluster_state: ok # cluster_slots_assigned: 16384 # cluster_slots_ok: 16384 # cluster_nodes: 6
10.4 Cluster監(jiān)控腳本
#!/bin/bash # script: redis_cluster_monitor.sh # 用途:監(jiān)控Redis Cluster狀態(tài) echo"=== Redis Cluster監(jiān)控 ===" INFO=$(redis-cli cluster info) STATE=$(echo"$INFO"| grep"^cluster_state:"| cut -d: -f2 | tr -d' ') SLOTS=$(echo"$INFO"| grep"^cluster_slots_assigned:"| cut -d: -f2 | tr -d' ') SLOTS_OK=$(echo"$INFO"| grep"^cluster_slots_ok:"| cut -d: -f2 | tr -d' ') NODES=$(echo"$INFO"| grep"^cluster_nodes:"| cut -d: -f2 | tr -d' ') echo"集群狀態(tài):$STATE" echo"已分配槽:$SLOTS" echo"正常槽:$SLOTS_OK" echo"節(jié)點(diǎn)數(shù):$NODES" # 檢查槽分配 if["$SLOTS"!="16384"];then echo" 槽分配不完整!" fi if["$SLOTS"!="$SLOTS_OK"];then echo" 存在故障槽!" fi # 檢查節(jié)點(diǎn)狀態(tài) echo"" echo"節(jié)點(diǎn)詳情:" redis-cli cluster nodes |whilereadline;do echo" $line" done
11. 監(jiān)控工具對(duì)比
11.1 redis-cli內(nèi)置工具
# 實(shí)時(shí)監(jiān)控 redis-cli MONITOR # 實(shí)時(shí)統(tǒng)計(jì) redis-cli INFO # 大鍵掃描 redis-cli --bigkeys # 延遲測(cè)試 redis-cli --latency redis-cli --latency-history # 慢查詢 redis-cli SLOWLOG GET 10 # 內(nèi)存分析 redis-cli MEMORY STATS redis-cli MEMORY USAGE key
11.2 Prometheus + Grafana
# prometheus.yml scrape_configs: -job_name:'redis' static_configs: -targets:['localhost:6379'] metrics_path:/metrics
關(guān)鍵指標(biāo):
# redis_exporter采集的指標(biāo) redis_memory_used_bytes redis_memory_max_bytes redis_connected_clients redis_commands_total redis_command_duration_seconds_total redis_up
11.3 Grafana儀表盤
推薦使用社區(qū)儀表盤:
Redis Dashboard (ID: 763)
Redis / Prometheus (ID: 14091)
11.4 監(jiān)控工具對(duì)比
| 工具 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用場(chǎng)景 |
|---|---|---|---|
| redis-cli | 無(wú)需安裝,功能全面 | 無(wú)法長(zhǎng)期存儲(chǔ) | 臨時(shí)診斷 |
| Prometheus | 時(shí)序存儲(chǔ),告警 | 需要額外組件 | 生產(chǎn)監(jiān)控 |
| Grafana | 可視化豐富 | 依賴其他數(shù)據(jù)源 | 數(shù)據(jù)展示 |
| redis_exporter | 標(biāo)準(zhǔn)化采集 | 有資源開(kāi)銷 | Prometheus生態(tài) |
| Supervisor | 進(jìn)程管理 | 非監(jiān)控工具 | 進(jìn)程?;?/td> |
12. 告警閾值設(shè)置參考
12.1 內(nèi)存告警
# Prometheus告警規(guī)則
groups:
-name:redis
rules:
# 內(nèi)存使用率警告
-alert:RedisMemoryUsageHigh
expr:redis_memory_used_bytes/redis_memory_max_bytes>0.8
for:5m
labels:
severity:warning
annotations:
summary:"Redis內(nèi)存使用率高"
description:"實(shí)例{{ $labels.instance }}內(nèi)存使用率{{ $value | humanizePercentage }}"
# 內(nèi)存使用率危急
-alert:RedisMemoryUsageCritical
expr:redis_memory_used_bytes/redis_memory_max_bytes>0.9
for:1m
labels:
severity:critical
annotations:
summary:"Redis內(nèi)存使用率危急"
description:"實(shí)例{{ $labels.instance }}內(nèi)存即將耗盡,請(qǐng)立即處理!"
# 內(nèi)存碎片過(guò)高
-alert:RedisHighFragmentation
expr:redis_mem_fragmentation_ratio>1.5
for:10m
labels:
severity:warning
12.2 連接告警
# 連接數(shù)過(guò)高
-alert:RedisHighConnections
expr:redis_connected_clients/redis_config_maxclients>0.8
for:5m
labels:
severity:warning
12.3 復(fù)制告警
# 主從復(fù)制中斷 -alert:RedisReplicationDown expr:redis_connected_slaves1 ? ? ? ??for:?1m ? ? ? ??labels: ? ? ? ? ??severity:?critical ? ? ? ??for:?1m
12.4 性能告警
# 內(nèi)存驅(qū)逐過(guò)多
-alert:RedisHighEviction
expr:rate(redis_evicted_keys_total[5m])>10
for:5m
labels:
severity:warning
# 命令拒絕
-alert:RedisCommandRejected
expr:redis_rejected_commands_total>0
for:1m
labels:
severity:critical
13. 總結(jié):監(jiān)控大盤設(shè)計(jì)
13.1 核心監(jiān)控指標(biāo)
必選指標(biāo)(Critical):
內(nèi)存使用率 used_memory / maxmemory
客戶端連接數(shù) connected_clients
主從復(fù)制狀態(tài) master_link_status
持久化狀態(tài) last_bgsave_status
重要指標(biāo)(Important):
QPS instantaneous_ops_per_sec
復(fù)制延遲 slave_repl_offset
內(nèi)存碎片率 mem_fragmentation_ratio
淘汰鍵數(shù)量 evicted_keys
命令執(zhí)行時(shí)間 commandstats
可選指標(biāo)(Optional):
Lua腳本內(nèi)存 used_memory_lua
客戶端追蹤數(shù) tracking_clients
阻塞客戶端數(shù) blocked_clients
13.2 監(jiān)控Checklist
【基礎(chǔ)設(shè)施層】 □ 進(jìn)程存活 (redis-cli PING) □ 進(jìn)程重啟次數(shù) □ 運(yùn)行時(shí)間 (uptime) 【內(nèi)存層】 □ 內(nèi)存使用率 □ 內(nèi)存碎片率 □ 淘汰策略生效次數(shù) □ maxmemory配置 【連接層】 □ 客戶端連接數(shù) □ 阻塞客戶端數(shù) □ 最大連接數(shù)限制 【持久化層】 □ RDB最后保存狀態(tài) □ AOF最后寫(xiě)入狀態(tài) □ BGSAVE執(zhí)行情況 【復(fù)制層】 □ 主從連接狀態(tài) □ 復(fù)制延遲 □ 從節(jié)點(diǎn)數(shù)量 【性能層】 □ QPS □ 命令執(zhí)行時(shí)間 □ 慢查詢數(shù)量
13.3 告警處理流程
【告警觸發(fā)】 │ ▼ 【確認(rèn)告警有效性】 │ ▼ 【初步判斷】 - 內(nèi)存告警 → 檢查數(shù)據(jù)增長(zhǎng)、淘汰策略 - 連接告警 → 檢查連接泄漏、空閑連接 - 復(fù)制告警 → 檢查網(wǎng)絡(luò)、從節(jié)點(diǎn)狀態(tài) - 性能告警 → 檢查慢查詢、大鍵 │ ▼ 【快速處理】 - 擴(kuò)容內(nèi)存 - 清理連接 - 重啟復(fù)制 │ ▼ 【根因分析】 - 分析數(shù)據(jù)增長(zhǎng)原因 - 檢查代碼邏輯 - 優(yōu)化配置參數(shù) │ ▼ 【長(zhǎng)效機(jī)制】 - 調(diào)整監(jiān)控閾值 - 優(yōu)化容量規(guī)劃 - 完善告警規(guī)則
13.4 監(jiān)控命令速查
| 指標(biāo) | 查看命令 | 監(jiān)控腳本函數(shù) |
|---|---|---|
| 內(nèi)存 | INFO memory | grep used_memory |
| 連接 | INFO clients | grep connected_clients |
| 持久化 | INFO persistence | grep rdb/aof |
| 復(fù)制 | INFO replication | grep slave/master |
| 鍵空間 | INFO keyspace | grep db0 |
| 命令 | INFO commandstats | cmdstat_* |
| 性能 | INFO stats | instantaneous_ops_per_sec |
參考信息
版本信息:
Redis:7.4.x
Prometheus:2.50.x
Grafana:11.x
redis_exporter:最新穩(wěn)定版
操作系統(tǒng):Rocky Linux 9.4
相關(guān)文檔:
Redis官方文檔:Monitoring
Prometheus redis_exporter
Grafana Redis Dashboard
延伸閱讀:
《Redis in Action》
Redis University: Redis for Operations
-
Linux
+關(guān)注
關(guān)注
88文章
11798瀏覽量
219387 -
數(shù)據(jù)庫(kù)
+關(guān)注
關(guān)注
7文章
4072瀏覽量
68479 -
Redis
+關(guān)注
關(guān)注
0文章
394瀏覽量
12240
原文標(biāo)題:運(yùn)維干貨|Redis 應(yīng)用監(jiān)控指標(biāo)大盤點(diǎn),附監(jiān)控配置要點(diǎn)
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
2012年模擬行業(yè)熱門事件大盤點(diǎn)Top10
汽車動(dòng)力系統(tǒng)大盤點(diǎn):助你設(shè)計(jì)絕佳方案
智能硬件相關(guān)技術(shù)大盤點(diǎn)
如何給你的OSS資源加上監(jiān)控
三極管三種接法大盤點(diǎn)
Android谷歌手機(jī)大盤點(diǎn)(已成主流趨勢(shì))
智能手機(jī)、平板電腦及便攜式電腦連接器大盤點(diǎn)
2016年十大指紋識(shí)別芯片品牌大盤點(diǎn)
詳細(xì)圖文介紹中控視頻監(jiān)控93系列-智能NVR產(chǎn)品
各種計(jì)算機(jī)語(yǔ)言的經(jīng)典書(shū)籍大盤點(diǎn)
全面分析Redis的最佳實(shí)踐優(yōu)化
面試題:監(jiān)控Redis哪些指標(biāo)
Redis應(yīng)用監(jiān)控指標(biāo)大盤點(diǎn)
評(píng)論