D炸天的Redis,該如何監控?
本文重點講述Redis的哪些metrics需要重要監控(篇幅有限,不能涵蓋所有),以及我們如何獲取這些metrics數據。從而確保對我們應用至關重要的Redis是否健康運行,以及當出現問題時能及時通知我們。
吞吐量
吞吐量包括Redis實例歷史總吞吐量,以及每秒鐘的吞吐量。可以通過命令info stats中的幾個得到我們要監控的吞吐量:
- # 從Rdis上一次啟動以來總計處理的命令數
- total_commands_processed:2255
- # 當前Redis實例的OPS
- instantaneous_ops_per_sec:12
- # 網絡總入量
- total_net_input_bytes:34312
- # 網絡總出量
- total_net_output_bytes:78215
- # 每秒輸入量,單位是kb/s
- instantaneous_input_kbps:1.20
- # 每秒輸出量,單位是kb/s
- instantaneous_output_kbps:2.62
內存利用率
Redis高性能保障的一個重要資源就是足夠的內存。Used memory表示Redis已經分配的總內存大小。我們可以通過info memory命令獲取所有內存利用了相關數據,其結果如下:
- 127.0.0.1:6379> info memory
- # Memory
- used_memory:1007888
- used_memory_human:984.27K
- used_memory_rss:581632
- used_memory_rss_human:568.00K
- used_memory_peak:1026064
- used_memory_peak_human:1002.02K
- total_system_memory:8589934592
- total_system_memory_human:8.00G
- used_memory_lua:37888
- used_memory_lua_human:37.00K
- maxmemory:0
- maxmemory_human:0B
- maxmemory_policy:noeviction
- mem_fragmentation_ratio:0.58
- mem_allocator:libc
需要注意的是,如果我們沒有配置maxmemory(可以通過config get/set maxmemory查詢并在不重啟Redis實例的前提下設置),那么Redis可能會耗盡服務器所有可用內存,從而可能導致swap甚至被系統kill掉。
所以建議方案是配置maxmemory,并且配置maxmemory-policy(不要是默認的noviction)。即使這樣還不夠,因為如果并發比較大的話,緩存逐除策略可能會忙不過來,從而依然會有無法操作Redis的錯誤。所以強烈建議:在配置maxmemory-policy和maxmemory雙策略的前提下,對used_memory進行監控,建議是maxmemory的90%。例如maxmemory為10G,那么當used_memory達到9G的時候,進行相關預警,從而準備擴容。
緩存命中率
緩存命中率表示緩存的使用效率,很明顯,它通過公式:HitRate = keyspace_hits / (keyspace_hits + keyspace_misses) 計算得到。在info stats中恰好有這些數據:
- keyspace_hits:17
- keyspace_misses:1
緩存命中率建議不需要低于90%,越高越好。這個命中率越低,表示越多對緩存中沒有的KEY進行了訪問。可能是這些KEY已經過期、已經被刪除、已經被evict、或者壓根兒不存在的KEY非法訪問等原因。
緩存命中率越低,或導致越多的請求穿透Redis從MySQL(或者其他速度遠比Redis慢的存儲服務)獲取數據,從而導致越多的請求有更大的延遲,導致API耗時增加,影響用戶體驗。
如果是內存不足,那么需要擴容。例如info stats中的evicted_keys不為0,或者used_memory達到了內存上限。如果是用法問題,那么需要優化代碼。
客戶端連接數
這個值可以通過info clients中的字段connected_clients獲取,它會受到操作系統ulimit和redis的maxclients配置的限制。如果Rdis客戶端中報出獲取不到連接數的錯誤(異常信息:ERR max number of clients reached),需要排查這兩個地方是否限制了客戶端連接數。當然,也可能還有其他其他原因,比如客戶端BUG導致連接沒有釋放等。
慢日志
Redis和其他關系型數據庫一樣,也有命令執行的慢日志。慢日志收集的閾值可通過config set slowlog-log-slower-than配置,單位是微妙。默認是10000微秒,即10ms,筆者認為這個默認值設置的太大,建議將其調整到1ms。因為這個慢日志統計的時間只是命令執行的時間,不包括客戶端到服務端的時間,以及命令在服務端隊列中的等待時間。以Rdis的性能來說,正常的執行時間一般在10微秒級別(單實例OPS可以達到10W)。所以,設置slowlog-log-slower-than為1000,即1毫秒已經綽綽有余:
- redis> slowlog get
- 1) 1) (integer) 21 # Unique ID
- 2) (integer) 1439419285 # Unix timestamp
- 3) (integer) 19125 # Execution time in microseconds
- 4) 1) "keys" # Command
- ... ...
另外,可以通過命令slowlog reset清理掉所有保存的慢日志。
說明:Redis4.0或者更高的版本多了兩個額外的字段:客戶端IP端口以及客戶端名稱。客戶端名稱可以通過命令:client setname 進行自定義設置。
延遲監控
任何環境都會存在延遲,關鍵是看延遲是否在我們能接受的范圍內。一些影響會比較大的高延遲,可能會有很多的原因,例如:網絡原因、計算密集型命令、時間復雜度為O(n)的命令、系統內存不夠發生SWAP等。
Redis提供了非常多的工具來定位這些延遲問題。
- slowlog
即慢日志,前面已經有詳細的說明,這是非常重要的監控項。Redis是單線程處理命令,所以如果有執行時間比較長的命令,就會導致其他命令阻塞。
- latency monitor
latency monitoring是從Redis2.8.13開始引入的新特性,用來幫組定位延遲問題,它能夠記錄Redis產生延遲問題的可能原因。需要通過如下命令來開啟這個特性,當然,也可以在redis.conf中配置:
- config set latency-monitor-threshold ms
接下來可以通過如下命令檢查是否開啟成功:
- redis> latency latest
- 1) 1) "command" # Event name
- 2) (integer) 1539479413 # Unix timestamp
- 3) (integer) 381 # Latency of latest event
- 4) (integer) 6802 # All time maximum latency
- # 還可以查看引起延遲的歷史命令:
- redis> latency history command
- # 延遲診斷
- redis> latency doctor
- intrinsic latency
Redis服務內部延遲。通過執行命令:src/redis-cli --intrinsic-latency sec得到延遲統計數據,它的結果可以用來衡量Redis服務內部延遲時間。這個命令的總運行時間由最后一個參數sec決定。通過這個命令,我們能判定搭建的Redis服務性能是否正常。命令使用參考:
- afeideMBP:redis-3.2.11 litian$ src/redis-cli --intrinsic-latency 5
- Max latency so far: 1 microseconds.
- Max latency so far: 4 microseconds.
- Max latency so far: 11 microseconds.
- Max latency so far: 17 microseconds.
- Max latency so far: 115 microseconds.
- Max latency so far: 648 microseconds.
- 99087235 total runs (avg latency: 0.0505 microseconds / 50.46 nanoseconds per run).
- Worst run took 12842x longer than the average latency.
- network latency
前面使用--intrinsic-latency可以檢查Redis內部延遲情況,但是因為Redis是遠程緩存服務,命令執行時從客戶端到服務端的時間延遲并沒有得到統計。而且相比起內部延遲,Redis客戶端到服務端的網絡延遲影響更大,不確定因素也更多,比如網絡抖動等。Redis也提供了相關命令來統計網絡延遲情況,這個命令的本質就是通過ping你的Redis服務端來衡量響應時間。使用方法如下:
- afeideMBP:redis-3.2.11 litian$ src/redis-cli --latency -h 127.0.1.168 -p 6379
- min: 0, max: 1, avg: 0.18 (174 samples)
注意:這個命令會一直運行下去,除非你主動終止它。
cachecloud
通過上文我們可知,大部分的metrics都可以通過info命令得到,毫不夸張的說,info命令是窺探Redis最好的方法。所以,要監控要Redis,我們一定要熟悉info結果中每個字段的含義,然后結合自己的業務有針對性的定制化最適合我們業務的監控方案。但是info命令只是一個單機版的命令,而一般我們的生產環境是redis集群。那么我們需要一個專業的監控服務來將整個redis集群的metric聚合起來方便我們查看,筆者在這里強烈推薦cachecloud。GIthub地址為:https://github.com/sohutv/cachecloud,用過的都說好,嘿嘿~