細說Redis監控和告警

RaymondShee 8年前發布 | 11K 次閱讀 Redis NoSQL數據庫

對于任何應用服務和組件,都需要一套完善可靠譜監控方案。

尤其redis這類敏感的純內存、高并發和低延時的服務,一套完善的監控告警方案,是精細化運營的前提。

本文分幾節,細說Redis的監控和告警:

1.Redis監控告警的價值

2.Redis監控的數據采集

3.Redis告警策略

4.基于Open Falcon的Redis監控告警方案

Redis監控告警的價值

Redis監控告警的價值對每個角色都不同,重要的幾個方面:

  • redis故障快速通知,定位故障點;對于DBA,redis的可用性和性能故障需快速發現和定位解決。
  • 分析redis故障的Root cause
  • redis容量規劃和性能管理
  • redis硬件資源利用率和成本

redis故障快速發現,定位故障點和解決故障

當redis出現故障時,DBA應在盡可能短時間內發現告警;如果故障對服務是有損的(如大面積網絡故障或程序BUG),需立即通知SRE和RD啟用故障預案(如切換機房或啟用emergency switch)止損。

如果沒完善監控告警;假設由RD發現服務故障,再排查整體服務調用鏈去定位;甚于用戶發現用問題,通過客服投訴,再排查到redis故障的問題;整個redis故障的發現、定位和解決時間被拉長,把一個原本的小故障被”無限”放大。

分析redis故障的Root cause

任何一個故障和性能問題,其根本“誘因”往往只有一個,稱為這個故障的Root cause。

一個故障從DBA發現、止損、分析定位、解決和以后規避措施;最重要一環就是DBA通過各種問題表象,層層分析到Root cause;找到問題的根據原因,才能根治這類問題,避免再次發生。

完善的redis監控數據,是我們分析root cause的基礎和證據。

備注:Troubleshtooing定位Root cause,就像醫生通過病人的病歷和檢查報告找到“真正的病灶”,讓病人康復和少受苦,一樣有意思和復雜;或像刑警通過案件的證據分析和推理,尋找那個唯一的真相,一樣驚心動魄。(快看DBA又在吹牛了),其實在大型商業系統中,一次故障輕松就達直接損失數十萬(間接損失更大),那“抓住元兇”,避免它再次“作案”,同樣是“破案”。

問題表現是綜合情的,一般可能性較復雜,這里舉2個例子:

  • 服務調用Redis響應時間變大的性能總是;可能網絡問題,redis慢查詢,redis QPS增高達到性能瓶頸,redis fork阻塞和請求排隊,redis使用swap, cpu達到飽和(單核idle過低),aof fsync阻塞,網絡進出口資源飽和等等
  • redis使用內存突然增長,快達到maxmemory; 可能其個大鍵寫入,鍵個數增長,某類鍵平均長度突增,fork COW, 客戶端輸入/輸出緩沖區,lua程序占用等等

Root cause是要直觀的監控數據和證據,而非有技術支撐的推理分析。

  • redis響應抖動,分析定位root casue是bgsave時fork導致阻塞200ms的例子。而不是分析推理:redis進程rss達30gb,響應抖動時應該有同步,fork子進程時,頁表拷貝時要阻塞父進程,估計頁表大小xx,再根據內存copy連續1m數據要xx 納秒,分析出可能fork阻塞導致的。(要的不是這種分析)

    說明:糧廠有個習慣,在分析root cause盡量能拿到直觀證據。因為一旦引入推理步驟,每一步的推理結果都可能出現偏差,最終可能給出錯誤root cause. “元兇”又逃過一劫,它下次作案估計就會更大。所以建議任何小的故障或抖動,至少從個人或小組內部,深入分析找到root cause;這樣個人或組織都會成長快; 形成良好的氛圍。

Redis容量規劃和性能管理

通過分析redis資源使用和性能指標的監控歷史趨勢數據;對集群進行合理擴容(Scale-out)、縮容(Scale-back);對性能瓶頸優化處理等。

Redis資源使用飽和度監控,設置合理閥值;

一些常用容量指標:redis內存使用比例,swap使用,cpu單核的飽和度等;當資源使用容量預警時,能及時擴容,避免因資源使用過載,導致故障。

另一方面,如果資源利用率持續過低,及時通知業務,并進行redis集群縮容處理,避免資源浪費。

進一步,容器化管理redis后,根據監控數據,系統能自動地彈性擴容和縮容。

Redis性能監控管理,及時發現性能瓶頸,進行優化或擴容,把問題扼殺在”萌芽期“,避免它”進化“成故障。

Redis硬件資源利用率和成本

從老板角度來看,最關心的是成本和資源利用率是否達標。

如果資源不達標,就得推進資源優化整合;提高硬件利用率,減少資源浪費。砍預算,減成本。

資源利用率是否達標的數據,都是通過監控系統采集的數據。

這一小節,扯了這么多; 只是強調redis不是只有一個端口存活監控就可以了。

下面進入主題,怎么采集redsis監控數。

老板曾說:監控告警和數據備份,是對DBA和SRE最基礎也是最高的要求;

當服務和存儲達到產品規模后,可認為“無監控,不服務;無備份,不存儲”。

Redis監控數據采集

redis監控的數據采集,數據采集1分鐘一次,分為下面幾個方面:

  • 服務器系統數據采集
  • Redis Server數據采集
  • Redis響應時間數據采集
  • Redis監控Screen

服務器系統監控數據采集

服務器系統的數據采集,這部分包含數百個指標. 采集方式現在監控平臺自帶的agent都會支持

如Zabbix和Open Falcon等,這里就不介紹采集方法。

我們從redis使用資源的特性,分析各個子系統的重要監控指標。

服務器存活監控

  • ping監控告警

CPU

  • 平均負載 (Load Average): 綜合負載指標(暫且歸類cpu子系統),當系統的子系統出現過度使用時,平均負載會升高。可說明redis的處理性能下降(平均響應時間變長、吞吐量降低)。
  • CPU整體利用率或飽和度 (cpu.busy): redis在高并發或時間復雜度高的指令,cpu整體資源飽和,導致redis性能下降,請求堆積。
  • CPU單核飽和度 (cpu.core.idle/core=0): redis是單進程模式,常規情況只使用一個cpu core, 單某個實例出現cpu性能瓶頸,導致性能故障,但系統一般24線程的cpu飽和度卻很低。所以監控cpu單核心利用率也同樣重樣。
  • CPU上下文切換數 (cpu.switches):context swith過高xxxxxx

內存和swap

  • 系統內存余量大小 (mem.memfree):redis是純內存系統,系統內存必須保有足夠余量,避免出現OOM,導致redis進程被殺,或使用swap導致redis性能驟降。
  • 系統swap使用量大小 (mem.swapused):redis的”熱數據“只要進入swap,redis處理性能就會驟降; 不管swap分區的是否是SSD介質。OS對swap的使用材質還是disk store. 這也是作者早期redis實現VM,后來又放棄的原因。

說明:系統內存余量合理,給各種緩沖區,fork cow足夠的內存空間。

另一個問題:我的系統使用Redis緩存集群,”不怕掛,就怕慢“,或redis集群高可用做得厲害;這樣redis的服務器是否能關閉swap呢?

磁盤

  • 磁盤分區的使用率 (df.bytes.used.percent):磁盤空間使用率監控告警,確保有足磁盤空間用AOF/RDB, 日志文件存儲。不過 redis服務器一般很少出現磁盤容量問題
  • 磁盤IOPS的飽和度(disk.io.util):如果有AOF持久化時,要注意這類情況。如果AOF持久化,每秒sync有堆積,可能導致寫入stall的情況。 另外磁盤順序吞吐量還是很重要,太低會導致復制同步RDB時,拉長同步RDB時間。(期待diskless replication)

網絡

  • 網絡吞吐量飽和度(net.if.out.bytes/net.if.in.bytes):如果服務器是千兆網卡(Speed: 1000Mb/s),單機多實例情況,有異常的大key容量導致網卡流量打滿。redis整體服務等量下降,苦于出現故障切換。
  • 丟包率 :Redis服務響應質量受影響

Redis Server監控數據采集

通過redis實例的狀態數據采集,采集監控數據的命令

ping,info all, slowlog get/len/reset/cluster info/config get

Redis存活監控

  • redis存活監控 (redis_alive):redis本地監控agent使用ping,如果指定時間返回PONG表示存活,否則redis不能響應請求,可能阻塞或死亡。
  • redis uptime監控 (redis_uptime):uptime_in_seconds

Redis 連接數監控

  • 連接個數 (connected_clients):客戶端連接個數,如果連接數過高,影響redis吞吐量。常規建議不要超過5000.參考 官方benchmarks
  • 連接數使用率(connected_clients_pct): 連接數使用百分比,通過(connected_clients/macclients)計算;如果達到1,redis開始拒絕新連接創建。

    127.0.0.1:6380> set mykey myvalue
    (error) ERR max number of clients reached
    127.0.0.1:6380>
    
  • 拒絕的連接個數(rejected_connections): redis連接個數達到maxclients限制,拒絕新連接的個數。

  • 新創建連接個數 (total_connections_received): 如果新創建連接過多,過度地創建和銷毀連接對性能有影響,說明短連接嚴重或連接池使用有問題,需調研代碼的連接設置。
  • list阻塞調用被阻塞的連接個數 (blocked_clients): BLPOP這類命令沒使用過,如果監控數據大于0,還是建議排查原因。

Redis內存監控

  • redis分配的內存大小 (used_memory): redis真實使用內存,不包含內存碎片;單實例的內存大小不建議過大,常規10~20GB以內。
  • redis內存使用比例(used_memory_pct): 已分配內存的百分比,通過(used_memory/maxmemory)計算;對于redis存儲場景會比較關注,未設置淘汰策略(maxmemory_policy)的,達到maxmemory限制不能寫入數據。

    127.0.0.1:6380> setmykey myvalue
    (error) OOM commandnot allowed when used memory >'maxmemory'.
    127.0.0.1:6380>
    
  • redis進程使用內存大小(used_memory_rss): 進程實際使用的物理內存大小,包含內存碎片;如果rss過大導致內部碎片大,內存資源浪費,和fork的耗時和cow內存都會增大。

  • redis內存碎片率 (mem_fragmentation_ratio): 表示(used_memory_rss/used_memory),碎片率過大,導致內存資源浪費;

    說明:

    1、如果內存使用很小時,mem_fragmentation_ratio可以遠大于1的情況,這個告警值不好設置,需參考used_memory大小。

    2、如果mem_fragmentation_ratio小于1,表示redis已使用swap分區

Redis綜合性能監控

Redis Keyspace

redis鍵空間的狀態監控

  • 鍵個數 (keys): redis實例包含的鍵個數。建議控制在1kw內;單實例鍵個數過大,可能導致過期鍵的回收不及時。
  • 設置有生存時間的鍵個數 (keys_expires): 是純緩存或業務的過期長,都建議對鍵設置TTL; 避免業務的死鍵問題. (expires字段)
  • 估算設置生存時間鍵的平均壽命 (avg_ttl): redis會抽樣估算實例中設置TTL鍵的平均時長,單位毫秒。如果無TTL鍵或在Slave則avg_ttl一直為0
  • LRU淘汰的鍵個數 (evicted_keys): 因used_memory達到maxmemory限制,并設置有淘汰策略的實例;(對排查問題重要,可不設置告警)
  • 過期淘汰的鍵個數 (expired_keys): 刪除生存時間為0的鍵個數;包含主動刪除和定期刪除的個數。

Redis qps

  • redis處理的命令數 (total_commands_processed): 監控采集周期內的平均qps,
    redis單實例處理達數萬,如果請求數過多,redis過載導致請求堆積。
  • redis當前的qps (instantaneous_ops_per_sec): redis內部較實時的每秒執行的命令數;可和total_commands_processed監控互補。

Redis cmdstat_xxx

這小節講解,redis記錄執行過的所有命令; 通過info all的Commandstats節采集數據.

  • 每類命令執行的次數 (cmdstat_xxx): 這個值用于分析redis抖動變化比較有用

以下表示:每個命令執行次數,總共消耗的CPU時長(單個微秒),平均每次消耗的CPU時長(單位微秒)

# Commandstats
cmdstat_set:calls=6,usec=37,usec_per_call=6.17
cmdstat_lpush:calls=4,usec=32,usec_per_call=8.00
cmdstat_lpop:calls=4,usec=33,usec_per_call=8.25

Redis Keysapce hit ratio

redis鍵空間請求命中率監控,通過此監控來度量redis緩存的質量,如果未命中率或次數較高,可能因熱點數據已大于redis的內存限制,導致請求落到后端存儲組件,可能需要擴容redis緩存集群的內存容量。當然也有可能是業務特性導致。

  • 請求鍵被命中次數 (keyspace_hits): redis請求鍵被命中的次數
  • 請求鍵未被命中次數 (keyspace_misses): redis請求鍵未被命中的次數;當命中率較高如95%,如果請求量大,未命中次數也會很多。可參考Baron大神寫的 Why you should ignore MySQL’s key cache hit ratio
  • 請求鍵的命中率 (keyspace_hit_ratio):使用keyspace_hits/(keyspace_hits+keyspace_misses)計算所得,是度量Redis緩存服務質量的標準

Redis fork

redis在執行BGSAVE,BGREWRITEAOF命令時,redis進程有 fork 操作。而fork會對redis進程有個短暫的卡頓,這個卡頓redis不能響應任務請求。所以監控fork阻塞時長,是相當重要。

如果你的系統不能接受redis有500ms的阻塞,那么就要監控fork阻塞時長的變化,做好容量規劃。

  • 最近一次fork阻塞的微秒數 (latest_fork_usec): 最近一次Fork操作阻塞redis進程的耗時數,單位微秒。

redis network traffic

redis一般單機多實例部署,當服務器網絡流量增長很大,需快速定位是網絡流量被哪個redis實例所消耗了; 另外redis如果寫流量過大,可能導致slave線程“客戶端輸出緩沖區”堆積,達到限制后被Maser強制斷開連接,出現復制中斷故障。所以我們需監控每個redis實例網絡進出口流量,設置合適的告警值。

說明:網絡監控指標 ,需較高的版本才有,應該是2.8.2x以后

  • redis網絡入口流量字節數 (total_net_input_bytes)
  • redis網絡出口流量字節數 (total_net_output_bytes)
  • redis網絡入口kps (instantaneous_input_kbps)
  • redis網絡出口kps (instantaneous_output_kbps)

前兩者是累計值,根據監控平臺1個采集周期(如1分鐘)內平均每秒的流量字節數。

Redis慢查詢監控

redis慢查詢 是排查性能問題關鍵監控指標。因redis是單線程模型(single-threaded server),即一次只能執行一個命令,如果命令耗時較長,其他命令就會被阻塞,進入隊列排隊等待;這樣對程序性能會較大。

redis慢查詢保存在內存中,最多保存slowlog-max-len(默認128)個慢查詢命令,當慢查詢命令日志達到128個時,新慢查詢被加入前,會刪除最舊的慢查詢命令。因慢查詢不能持久化保存,且不能實時監控每秒產生的慢查詢個數。

我們建議的慢查詢監控方法:

  1. 設置合理慢查詢日志閥值,slowlog-log-slower-than, 建議1ms(如果平均1ms, redis qps也就只有1000)
  2. 設置全理慢查詢日志隊列長度,slowlog-max-len建議大于1024個,因監控采集周期1分鐘,建議,避免慢查詢日志被刪除;另外慢查詢的參數過多時,會被省略,對內存消耗很小
  3. 每次采集使用slowlog len獲取慢查詢日志個數
  4. 每次彩集使用slowlog get 1024 獲取所慢查詢,并轉存儲到其他地方,如MongoDB或MySQL等,方便排查問題;并分析當前慢查詢日志最長耗時微秒數。
  5. 然后使用slowlog reset把慢查詢日志清空,下個采集周期的日志長度就是最新產生的。

redis慢查詢的監控項:

  • redis慢查詢日志個數 (slowlog_len):每個采集周期出現慢查詢個數,如1分鐘出現10次大于1ms的慢查詢
  • redis慢查詢日志最長耗時值 (slowlog_max_time):獲取慢查詢耗時最長值,因有的達10秒以下的慢查詢,可能導致復制中斷,甚至出來主從切換等故障。

Redis持久化監控

redis存儲場景的集群,就得 redis持久化 保障數據落地,減少故障時數據丟失。這里分析redis rdb數據持久化的幾個監控指標。

  • 最近一次rdb持久化是否成功 (rdb_last_bgsave_status):如果持久化未成功,建議告警,說明備份或主從復制同步不正常。或redis設置有”stop-writes-on-bgsave-error”為yes,當save失敗后,會導致redis不能寫入操作
  • 最近一次成功生成rdb文件耗時秒數 (rdb_last_bgsave_time_sec):rdb生成耗時反應同步時數據是否增長; 如果遠程備份使用redis-cli –rdb方式遠程備份rdb文件,時間長短可能影響備份線程客戶端輸出緩沖內存使用大小。
  • 離最近一次成功生成rdb文件,寫入命令的個數 (rdb_changes_since_last_save):即有多少個寫入命令沒有持久化,最壞情況下會丟失的寫入命令數。建議設置監控告警
  • 離最近一次成功rdb持久化的秒數 (rdb_last_save_time): 最壞情況丟失多少秒的數據寫入。使用當前時間戳 - 采集的rdb_last_save_time(最近一次rdb成功持久化的時間戳),計算出多少秒未成功生成rdb文件

Redis復制監控

不論使用何種redis集群方案, redis復制 都會被使用。

復制相關的監控告警項:

  • redis角色 (redis_role):實例的角色,是master or slave
  • 復制連接狀態 (master_link_status): slave端可查看它與master之間同步狀態;當復制斷開后表示down,影響當前集群的可用性。需設置監控告警。
  • 復制連接斷開時間長度 (master_link_down_since_seconds):主從服務器同步斷開的秒數,建議設置時長告警。
  • 主庫多少秒未發送數據到從庫 (master_last_io_seconds):如果主庫超過repl-timeout秒未向從庫發送命令和數據,會導致復制斷開重連。詳細分析見文章: Redis復制中斷和無限同步問題 。 在slave端可監控,建議設置大于10秒告警
  • 從庫多少秒未向主庫發送REPLCONF命令 (slave_lag): 正常情況從庫每秒都向主庫,發送REPLCONF ACK命令;如果從庫因某種原因,未向主庫上報命令,主從復制有中斷的風險。通過在master端監控每個slave的lag值。
  • 從庫是否設置只讀 (slave_read_only):從庫默認只讀禁止寫入操作,監控從庫只讀狀態;
    如果關閉從庫只讀,有寫入數據風險。關于主從數據不一致,見文章分析: Redis復制主從數據不-致
  • 主庫掛載的從庫個數 (connected_slaves):主庫至少保證一個從庫,不建議設置超過2個從庫。
  • 復制積壓緩沖區是否開啟 (repl_backlog_active):主庫默認開啟復制積壓緩沖區,用于應對短時間復制中斷時,使用 部分同步 方式。
  • 復制積壓緩沖大小 (repl_backlog_size):主庫復制積壓緩沖大小默認1MB,因為是redis server共享一個緩沖區,建議設置100MB.

    說明: 關于根據實際情況,設置合適大小的復制緩沖區。可以通過master_repl_offset指標計算每秒寫入字節數,同時乘以希望多少秒內閃斷使用“部分同步”方式。

Redis集群監控

這里所寫 redis官方集群方案 的監控指標

數據基本通過cluster info和info命令采集。

  • 實例是否啟用集群模式 (cluster_enabled): 通過info的cluster_enabled監控是否啟用集群模式。
  • 集群健康狀態 (clusster_state):如果當前redis發現有failed的slots,默認為把自己cluster_state從ok個性為fail, 寫入命令會失敗。如果設置cluster-require-full-coverage為NO,則無此限制。
  • 集群數據槽slots分配情況 (cluster_slots_assigned):集群正常運行時,默認16384個slots
  • 檢測下線的數據槽slots個數 (cluster_slots_fail):集群正常運行時,應該為0. 如果大于0說明集群有slot存在故障。
  • 集群的分片數 (cluster_size):集群中設置的分片個數
  • 集群的節點數 (cluster_known_nodes):集群中redis節點的個數

Redis響應時間監控

響應時間 是衡量一個服務組件性能和質量的重要指標。使用redis的服務通常對響應時間都十分敏感,比如要求99%的響應時間達10ms以內。

因redis的慢查詢日志只計算命令的cpu占用時間,不會考慮排隊或其他耗時。

  • 最長響應時間 (respond_time_max):最長響應時間的毫秒數
  • 99%的響應時間長度 (respond_time_99_max):
  • 99%的平均響應時間長度 (respond_time_99_avg):
  • 95%的響應時間長度 (respond_time_95_max):
  • 95%的平均響應時間長度 (respond_time_95_avg):

響應時間監控的方式建議,最簡單方法,使用 Percona tcprstat

 

來自:https://zhuoroger.github.io/2016/08/20/redis-monitor-and-alarm/?

 

 本文由用戶 RaymondShee 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!