<b>3.1 慢查詢分析</b>
許多存儲系統(例如mysql)提供慢查詢日志幫助開發和運維人員定位系統存在的慢操作。所謂慢查詢日志就是系統在指令執行前後計算每條指令的執行時間,當超過預設閥值,就将這條指令的相關資訊(例如:發生時間,耗時,指令的詳細資訊)記錄下來,redis也提供了類似的功能。
如圖3-1所示,redis用戶端執行一條指令分為如下4個部分:
圖3-1 一條用戶端指令的生命周期
1)發送指令
2)指令排隊
3)指令執行
4)傳回結果
需要注意,慢查詢隻統計步驟3)的時間,是以沒有慢查詢并不代表用戶端沒有逾時問題。
<b>3.1.1 慢查詢的兩個配置參數</b>
對于慢查詢功能,需要明确兩件事:
預設閥值怎麼設定
慢查詢記錄存放在哪
redis提供了slowlog-log-slower-than和slowlog-max-len配置來解決這兩個問題。從字面意思就可以看出,slowlog-log-slower-than就是那個預設閥值,它的機關是微秒(1秒 = 1000毫秒 =
1?000?000微秒),預設值是10?000,假如執行了一條“很慢”的指令(例如keys *),如果它的執行時間超過了10?000微秒,那麼它将被記錄在慢查詢日志中。
如果slowlog-log-slower-than=0會記錄所有的指令,slowlog-log-slower-
than<0對于任何指令都不會進行記錄。
從字面意思看,slowlog-max-len隻是說明了慢查詢日志最多存儲多少條,并沒有說明存放在哪裡
實際上redis使用了一個清單來存儲慢查詢日志,slowlog-max-len就是清單的最大長度。一個新的指令滿足慢查詢條件時被插入到這個清單中,當慢查詢日志清單已處于其最大長度時,最早插入的一個指令将從清單中移出,例如slowlog-max-len設定為5,當有第6條慢查詢插入的話,那麼隊頭的第一條資料就出列,第6條慢查詢就會入列。
在redis中有兩種修改配置的方法,一種是修改配置檔案,另一種是使用config set指令動态修改。例如下面使用config set指令将slowlog-log-slower-than設定為20?000微秒,slowlog-max-len設定為1000:
config set slowlog-log-slower-than 20000
config set slowlog-max-len 1000
config rewrite
如果要redis将配置持久化到本地配置檔案,需要執行config rewrite指令,如圖3-2所示。
圖3-2 config rewrite指令重寫配置檔案
雖然慢查詢日志是存放在redis記憶體清單中的,但是redis并沒有暴露這個清單的鍵,而是通過一組指令來實作對慢查詢日志的通路和管理。下面介紹這幾個指令。
(1)擷取慢查詢日志
slowlog get [n]
下面操作傳回目前redis的慢查詢,參數n可以指定條數:
127.0.0.1:6379> slowlog get
1)
1) (integer) 666
2) (integer) 1456786500
3) (integer) 11615
4) 1) "bgrewriteaof"
2)
1) (integer) 665
2) (integer) 1456718400
3) (integer) 12006
4) 1) "setex"
2) "video_info_200"
3) "300"
4) "2"
...
可以看到每個慢查詢日志有4個屬性組成,分别是慢查詢日志的辨別id、發生時間戳、指令耗時、執行指令和參數,慢查詢清單如圖3-3所示。
圖3-3 慢查詢日志資料結構
(2)擷取慢查詢日志清單目前的長度
slowlog len
例如,目前redis中有45條慢查詢:
127.0.0.1:6379> slowlog len
(integer) 45
(3)慢查詢日志重置
slowlog reset
實際是對清單做清理操作,例如:
127.0.0.1:6379> slowlog reset
ok
(integer) 0
<b>3.1.2 最佳實踐</b>
慢查詢功能可以有效地幫助我們找到redis可能存在的瓶頸,但在實際使用過程中要注意以下幾點:
slowlog-max-len配置建議:線上建議調大慢查詢清單,記錄慢查詢時redis會對長指令做截斷操作,并不會占用大量記憶體。增大慢查詢清單可以減緩慢查詢被剔除的可能,例如線上可設定為1000以上。
slowlog-log-slower-than配置建議:預設值超過10毫秒判定為慢查詢,需要根據redis并發量調整該值。由于redis采用單線程響應指令,對于高流量的場景,如果指令執行時間在1毫秒以上,那麼redis最多可支撐ops不到1000。是以對于高ops場景的redis建議設定為1毫秒。
慢查詢隻記錄指令執行時間,并不包括指令排隊和網絡傳輸時間。是以用戶端執行指令的時間會大于指令實際執行時間。因為指令執行排隊機制,慢查詢會導緻其他指令級聯阻塞,是以當用戶端出現請求逾時,需要檢查該時間點是否有對應的慢查詢,進而分析出是否為慢查詢導緻的指令級聯阻塞。
由于慢查詢日志是一個先進先出的隊列,也就是說如果慢查詢比較多的情況下,可能會丢失部分慢查詢指令,為了防止這種情況發生,可以定期執行slow get指令将慢查詢日志持久化到其他存儲中(例如mysql),然後可以制作可視化界面進行查詢,第13章介紹的redis私有雲cachecloud提供了這樣的功能,好的工具可以讓問題排查事半功倍。