通過prometheus監(jiān)控redis實時運行狀態(tài)的操作方法
引言
在現(xiàn)代微服務架構中,Redis被廣泛應用于緩存、消息隊列及其他場景。為了確保Redis集群的高可用性和性能,我們需要實時監(jiān)控其狀態(tài)與指標。本文將全面講解如何通過prometheus監(jiān)控redis運行的各項指標,讓數(shù)據(jù)實時可知。
1、安裝配置redis
1)安裝redis
yum install redis -y
2)調(diào)整redis內(nèi)使用的最大內(nèi)存
vim /etc/redis/redis.conf maxmemory 200mb
3)啟動redis
systemctl start redis
redis本身就有info命令,可以哦查看redis狀態(tài),但是并不兼容prometheus的數(shù)據(jù)格式
因此,需要借助exporter來暴露指標
2、安裝配置redis_exporter
1)訪問redis_exporter的github地址
https://github.com/oliver006/redis_exporter
下載redis_exporter
直接下載最新版
2)解壓redis_exporter
tar xf redis_exporter-v1.67.0.linux-amd64.tar.gz -C /etc/ ln -s /etc/redis_exporter-v1.67.0.linux-amd64/ /etc/redis_exporter
3)配置redis_exporter啟動文件
先看下redis_exporter啟動參數(shù)
默認監(jiān)聽地址是9121
systemd啟動配置文件
cat /usr/lib/systemd/system/redis_exporter.service [Unit] Description=redis_exporter Documentation=https://github.com/oliver006/redis_exporter After=network.target [Service] ExecStart=/etc/redis_exporter/redis_exporter \ -redis.addr="redis://localhost:6379" -redis.password="" -web.listen-address=":9121" \ -web.telemetry-path="/metrics" \ ExecReload=/bin/kill -HUP $MAINPID TimeoutStopSec=20s Restart=always [Install] WantedBy=multi-user.target
4)啟動redis_exporter
systemctl enable redis_exporter.service --now
5)訪問redis_exporter的metrics
http://10.10.0.32:9121/metrics
3、配置prometheus
1)修改prometheus配置
vim /etc/prometheus/prometheus.yml - job_name: "redis_exporter" static_configs: - targets: ["jingtian03:9121"]
2)加載prometheus配置文件
curl -X POST http://localhost:9090/-/reload
3)檢查Prometheus的Status->Targets頁面
驗證 redis_exporter 是否已經(jīng)成功納入監(jiān)控中
查看下指標
4)模擬產(chǎn)生Redis相關數(shù)據(jù)
執(zhí)行如下腳本
1、Redis向db0庫,插入了50個key,然后嘗試隨機獲取100個key。由于總共的key只有50個,因此會有一半查詢命中一半miss。
2、Redis向db1庫,插入了100個key,但有60個key設定了過期時間;
[root@jingtian03 myredis ]#cat redis_data.sh #!/bin/bash # 定義Redis主機和端口 REDIS_HOST=localhost REDIS_PORT=6379 # Redis數(shù)據(jù)庫定義 DB0=0 DB1=1 # 定義key的總數(shù) TOTAL_KEYS=100 # 計算應設置過期時間的鍵的數(shù)量 EXPIRING_KEYS_COUNT=$(( TOTAL_KEYS * 60 / 100 )) # 向Redis db0插入一半的key for i in {1..50} do key="test-$i" value="test-$i" redis-cli -h $REDIS_HOST -p $REDIS_PORT -n $DB0 SET $key $value done # 隨機獲取100個key,一部分將獲取成功,一部分將miss for i in {1..100} do random_key_index=$(( ( RANDOM % TOTAL_KEYS ) + 1 )) key="test-$random_key_index" result=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -n $DB0 GET $key) if [ "$result" == "" ] then echo "MISS: $key" else echo "HIT: $key" fi done # 向Redis db1插入100個key,其中60%設置過期時間為10分鐘 for i in {1..100} do key="expire-test-$i" value="value-$i" # 對前60%的鍵設置過期時間 if [ $i -le $EXPIRING_KEYS_COUNT ] then redis-cli -h $REDIS_HOST -p $REDIS_PORT -n $DB1 SET $key $value EX 600 else redis-cli -h $REDIS_HOST -p $REDIS_PORT -n $DB1 SET $key $value fi done
執(zhí)行腳本
4、Redis常用指標與示例
針對Redis服務,我們可以利用Google的四個黃金信號來監(jiān)控其健康狀況。
這些信號包括:
延遲:監(jiān)控平均命令響應時間,以評估處理請求的效率。
流量:跟蹤每秒處理的命令數(shù)量、以及網(wǎng)絡的輸入/輸出速度,以便理解服務負載。
錯誤:統(tǒng)計命令失敗次數(shù)和連接被拒絕的情況,以識別潛在的服務問題。
飽和度:監(jiān)測內(nèi)存使用率和客戶端連接數(shù),以判斷服務的負載情況和容量限制。
1)redis健康狀態(tài)相關指標
啟動多少秒是累加的,不斷增大的,counter類型的,exporter將其標為gauge是錯誤的
案例1:檢查Redis是否存活
sum(redis_up) by (instance,job)
案例2:檢查Redis是否出現(xiàn)過重啟,只需要判斷啟動時間是否小于1分鐘即可。
sum(redis_uptime_in_seconds) by (instance,job) < 60 # redis運行了多長時間 sum(redis_uptime_in_seconds) by (instance,job) / 3600 # 小時 sum(redis_uptime_in_seconds) by (instance,job) / 86400 # 天
2)redis連接數(shù)相關指標
默認允許的最大連接數(shù)為10000
案例1:查詢當前 Redis 連接數(shù)與最大配置連接數(shù)的比率。
計算公式:( 當前客戶端連接數(shù) / 最大支持的客戶端連接數(shù) * 100 )
redis_connected_clients /redis_config_maxclients *100
案例2:查詢過去1小時內(nèi)是否有連接被拒絕,直接使用increase獲取一個小時的增量數(shù)據(jù)
increase(redis_rejected_connections_total[1h])
3)redis內(nèi)存相關指標
案例:redis當前使用的內(nèi)存達到最大內(nèi)存的比率。計算公式:( 當前內(nèi)存 /最大內(nèi)存 * 100 )
redis_memory_used_bytes / redis_memory_max_bytes * 100
4)redis命中率相關指標
案例1:查詢最近5分鐘,命令率和未命中率QPS
irate(redis_keyspace_hits_total[5m]) irate(redis_keyspace_misses_total[5m])
案例2:查詢Redis最近5分鐘,緩存成功命中率低于90% ,計算公式:(rate(5分鐘成功的命中率) / ( 5分鐘成功的命中率 + 5分鐘失敗的命中率) *100 )
irate(redis_keyspace_hits_total[5m]) / ( irate(redis_keyspace_hits_total[5m]) + irate(redis_keyspace_misses_total[5m]) ) * 100 < 90
5)redis key相關指標
案例1:計算Redis中,每個庫即將過期的key,占每個庫總key的比率。計算公式:( 每個庫過期的key / 每個庫總的key * 100 )
redis_db_keys_expiring / redis_db_keys * 100
案例2:計算Redis最近5分鐘,即將被驅(qū)逐的Key,占總key的比率。計算公式:( rate(最近5分鐘被驅(qū)逐的Key) / 總的key * 100 )
# 計算不同命令的失敗率。 irate(redis_commands_failed_calls_total[5m]) / irate(redis_commands_total[5m]) * 100 # 計算總的失敗比率 sum (irate(redis_commands_failed_calls_total[5m])) by (instance,job) / sum (irate(redis_commands_total[5m])) by (instance,job) * 100
6)redis執(zhí)行命令操作相關指標
案例1:計算Redis每分鐘,成功處理命令的QPS
irate(redis_commands_processed_total[1m])
# 模擬Redis的QPS小腳本 while true;do redis-cli keys "*" redis-cli set a b redis-cli get a sleep 0.1 done
案例2:計算Redis最近5分鐘,命令執(zhí)行失敗占執(zhí)行命令總數(shù)的比率。
計算公式:( irate(最近5分鐘失敗的命令數(shù)量) / irate(最近5分鐘執(zhí)行命令的總數(shù)量) * 100 )
# 計算不同命令的失敗率。 irate(redis_commands_failed_calls_total[5m]) / irate(redis_commands_total[5m]) * 100 # 計算總的失敗比率 sum (irate(redis_commands_failed_calls_total[5m])) by (instance,job) / sum (irate(redis_commands_total[5m])) by (instance,job) * 100
案例3:計算Redis最近5分鐘,被拒絕執(zhí)行的命令占執(zhí)行命令總數(shù)的比率。
計算公式:( irate(最近5分鐘拒絕的命令數(shù)量) / irate(最近5分鐘執(zhí)行命令的總數(shù)量) * 100 )
# 計算不同命令的拒絕率。 irate(redis_commands_rejected_calls_total[5m]) / irate(redis_commands_total[5m]) * 100 # 計算總的拒絕率 sum (irate(redis_commands_rejected_calls_total[5m])) by (instance,job) / sum (irate(redis_commands_total[5m])) by (instance,job) * 100
案例4:計算Redis在過去5分鐘內(nèi)每個成功執(zhí)行的命令,平均響應時間。
計算公式:( irate(5分鐘所花費總的時間) / rate(5分鐘執(zhí)行成功命令的次數(shù)))
sum(rate(redis_commands_duration_seconds_total[5m])) by (instance,job) / sum (rate(redis_commands_processed_total[5m])) by (instance,job)
7)redis備份相關指標
RDB方式備份
案例1:上一次RDB備份失敗。
redis_rdb_last_bgsave_status == 0
案例2:上一次RDB備份成功,但是備份時長超過了3s
redis_rdb_last_bgsave_duration_sec > 3 and redis_rdb_last_bgsave_status ==1
案例3:超過10小時沒有生成新的RDB備份文件。
計算公式:( (當前時間戳- 上一次RBD備份文件時間戳 ) > 36000 ),10小時等于36000秒( 60 *60 * 10 )
(time() - redis_rdb_last_save_timestamp_seconds) > 36000
AOF備份
redis_aof_enabled:1 AOF日志是否啟用 redis_aof_rewrite_in_progress:0 表示當前是否在進行寫入AOF日志操作 redis_aof_rewrite_scheduled:0 是否有AOF操作等待執(zhí)行。 redis_aof_last_rewrite_time_sec:-1 表示上次寫入AOF日志的時間戳 redis_aof_current_rewrite_time_sec:-1 當前正在執(zhí)行的AOF重寫操作已經(jīng)消耗的時間。 redis_aof_last_bgrewrite_status:ok 表示上次執(zhí)行AOF日志重寫的狀態(tài) redis_aof_last_write_status:ok 表示上次寫入AOF日志的狀態(tài) redis_aof_last_cow_size:0 AOF執(zhí)行中父進程與子進程相比執(zhí)行了多少修改 redis_aof_current_size:0 AOF日志的當前大小 redis_aof_base_size:0 最近一次重寫后AOF日志的大小。 redis_aof_pending_rewrite:0 是否有AOF操作在等待執(zhí)行。 redis_aof_buffer_length:0 AOF緩沖區(qū)的大小。 redis_aof_rewrite_buffer_length:0 AOF重寫緩沖區(qū)的大小。 redis_aof_pending_bio_fsync:0 在等待執(zhí)行的fsync操作的數(shù)量。 redis_aof_delayed_fsync:0 fsync操作延遲執(zhí)行的次數(shù)。
5、redis告警規(guī)則文件
1)編寫redis告警規(guī)則文件
cat /etc/prometheus/rules/redis_rules.yml
groups: - name: redis告警規(guī)則 rules: - alert: Redis實例宕機 expr: sum(redis_up) by (instance, job) == 0 for: 1m labels: severity: critical annotations: summary: "Redis實例宕機, {{ $labels.instance }} " description: "Redis實例 {{ $labels.instance }} 在過去1分鐘內(nèi)無法連接。" - alert: Redis實例重啟 expr: sum(redis_uptime_in_seconds) by (instance, job) < 60 for: 0m labels: severity: warning annotations: summary: "Redis實例 {{ $labels.instance }} 重啟" description: "Redis實例 {{ $labels.instance }} 出現(xiàn)重啟。當前運行時間:{{ $value }} 秒。" - alert: Redis連接數(shù)過高 expr: redis_connected_clients / redis_config_maxclients * 100 > 80 for: 5m labels: severity: warning annotations: summary: "Redis實例 {{ $labels.instance }} 連接數(shù)超過80%" description: "Redis實例 {{ $labels.instance }} 當前連接數(shù)占最大連接數(shù)的比率超過80%。當前比率: {{ $value }}%。" - alert: Redis連接被拒絕 expr: increase(redis_rejected_connections_total[1h]) > 0 for: 5m labels: severity: warning annotations: summary: "Redis實例 {{ $labels.instance }} 有連接被拒絕" description: "Redis實例 {{ $labels.instance }} 在過去1小時內(nèi)有連接被拒絕。當前被拒絕的連接數(shù): {{ $value }}。" - alert: Redis內(nèi)存使用率過高 expr: redis_memory_used_bytes / redis_memory_max_bytes * 100 > 80 for: 5m labels: severity: critical annotations: summary: "Redis實例 {{ $labels.instance }} 內(nèi)存使用率超過80%" description: "Redis實例 {{ $labels.instance }} 當前內(nèi)存使用率超過配置的最大內(nèi)存值的80%。當前內(nèi)存使用率: {{ $value }}%。" - alert: Redis緩存命中率低 expr: | irate(redis_keyspace_hits_total[5m]) / (irate(redis_keyspace_hits_total[5m]) + irate(redis_keyspace_misses_total[5m])) * 100 < 90 for: 10m labels: severity: warning annotations: summary: "Redis實例 {{ $labels.instance }} 緩存命中率低于90%" description: "Redis實例 {{ $labels.instance }} 最近5分鐘內(nèi)的緩存命中率低于90%。當前命中率: {{ $value }}%。" - alert: Redis即將過期的Key數(shù)量過多 expr: | sum(redis_db_keys_expiring) by (instance, job, db) / sum(redis_db_keys) by (instance, job, db) * 100 > 50 for: 5m labels: severity: warning annotations: summary: "Redis實例 {{ $labels.instance }} 中的數(shù)據(jù)庫 {{ $labels.db}} 有過多即將過期的Key" description: "Redis實例 {{ $labels.instance }} 中的數(shù)據(jù)庫 {{ $labels.db }} 有超過50%的Key即將過期。當前比率: {{ $value }}%。" - alert: RedisRDB備份失敗 expr: redis_rdb_last_bgsave_status == 0 for: 1m labels: severity: critical annotations: summary: "Redis實例 {{ $labels.instance }} RDB備份失敗" description: "Redis實例 {{ $labels.instance }} 最近的RDB備份嘗試失敗。" - alert: RedisRDB備份時間過長 expr: redis_rdb_last_bgsave_duration_sec > 3 and redis_rdb_last_bgsave_status == 1 for: 1m labels: severity: warning annotations: summary: "Redis實例 {{ $labels.instance }} RDB備份成功但耗時超過3秒" description: "Redis實例 {{ $labels.instance }} RDB備份成功,但備份耗時超過了3秒。持續(xù)時間: {{ $value }}秒。" - alert: RedisRDB備份過期 expr: (time() - redis_rdb_last_save_timestamp_seconds) > 36000 for: 5m labels: severity: critical annotations: summary: "Redis實例 {{ $labels.instance }} 超過10小時未進行RDB備份" description: "Redis實例 {{ $labels.instance }} 已超過10小時沒有生成新的RDB備份文件。" - alert: Redis命令拒絕率過高 expr: | sum(irate(redis_commands_rejected_calls_total[5m])) by (instance, job) / sum(irate(redis_commands_total[5m])) by (instance, job) * 100 > 25 for: 5m labels: severity: warning annotations: summary: "Redis實例 {{ $labels.instance }} 命令拒絕率超過25%" description: "Redis實例 {{ $labels.instance }} 的命令拒絕率超過了25%。當前拒絕率: {{ $value }}%。" - alert: Redis命令平均響應時間過長 expr: | sum(rate(redis_commands_duration_seconds_total[5m])) by (instance,job) / sum(rate(redis_commands_processed_total[5m])) by (instance, job) >0.250 for: 5m labels: severity: critical annotations: summary: "Redis實例 {{ $labels.instance }} 命令平均響應時間超過250ms" description: "Redis實例 {{ $labels.instance }} 的執(zhí)行命令平均響應時間超過了250毫秒。當前平均響應時間: {{ $value }}秒。"
2)查看告警規(guī)則
6、導入redis圖形
1)導入一個redis的grafana的模板,ID為763
2)運行一個redis的模擬數(shù)據(jù)腳本
cat redis_basic_data.sh #!/bin/bash # 模擬的 Redis 客戶端數(shù)量 CLIENTS=199 # Redis 服務器配置 REDIS_HOST="localhost" REDIS_PORT=6379 REDIS_PASSWORD="" # Redis 密碼 # 生成隨機字符串的函數(shù),用于鍵和值 # $1 是生成的字符串長度 generate_random_string() { cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-32} | head -n 1 } # 模擬 Redis 客戶端的行為 simulate_redis_client() { # 存儲隨機生成的鍵,用于后續(xù)的 GET 操作 declare -a keys # 打開 redis-cli 的交互式會話 ( # 如果設置了密碼,先認證 if [[ -n "$REDIS_PASSWORD" ]]; then echo "AUTH $REDIS_PASSWORD" fi # 持續(xù)發(fā)送命令 while true; do # 生成隨機鍵和值 key=$(generate_random_string 10) value=$(generate_random_string 20) # 隨機的過期時間,介于10到60秒之間 ttl=$((RANDOM % 50 + 10)) # SET 操作 echo "SET $key $value EX $ttl" # 將鍵存儲在數(shù)組中,用于模擬 GET keys+=("$key") # 隨機決定是否執(zhí)行 GET if [ $((RANDOM % 2)) -eq 0 ]; then # 模擬命中和未命中 if [ $((RANDOM % 10)) -lt 8 ]; then # 80% 概率嘗試獲取一個存在的鍵,模擬命中 get_key="${keys[$((RANDOM % ${#keys[@]}))]}" else # 20% 概率嘗試獲取一個不存在的鍵,模擬未命中 get_key=$(generate_random_string 10) fi # GET 操作 echo "GET $get_key" fi # 操作間隔,減少服務器壓力 sleep 1 done ) | redis-cli -h $REDIS_HOST -p $REDIS_PORT --pipe } # 啟動多個客戶端 for ((i=0; i<CLIENTS; i++)); do simulate_redis_client & echo "Started Redis client simulation $i" done # 等待所有后臺進程 wait
客戶端數(shù)量增加
以上就是通過prometheus監(jiān)控redis實時運行狀態(tài)的操作方法的詳細內(nèi)容,更多關于prometheus監(jiān)控redis運行狀態(tài)的資料請關注腳本之家其它相關文章!
相關文章
Redis過期事件監(jiān)聽器的完整實現(xiàn)步驟
要使用 Redis 過期事件監(jiān)聽器來更新數(shù)據(jù)庫狀態(tài),我們需要確保 Redis 的事件通知已啟用,并實現(xiàn)監(jiān)聽器來捕獲過期的鍵,并根據(jù)需要更新數(shù)據(jù)庫,本文給大家介紹了Redis過期事件監(jiān)聽器的完整實現(xiàn)步驟,需要的朋友可以參考下2024-10-10解決Redis報錯MISCONF?Redis?is?configured?to?save?RDB?snap
這篇文章主要給大家介紹了關于如何解決Redis報錯MISCONF?Redis?is?configured?to?save?RDB?snapshots的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-11-11Unable?to?connect?to?Redis無法連接到Redis解決的全過程
這篇文章主要給大家介紹了關于Unable?to?connect?to?Redis無法連接到Redis解決的相關資料,文中通過圖文以及實例代碼將解決的過程介紹的非常詳細,需要的朋友可以參考下2023-03-03