經過前面4篇筆記,你們對redis的基本概念及配置已經有了解,本篇筆記重點說明如何經過官方發佈的redis sentinel工具來監控redis的運行狀態。另外,對sentinel使用過程當中的注意事項作些討論。redis
1. Redis Sentinel功能
Redis Sentinel是一套用於管理Redis實例的分佈式系統,主要完成3項任務:
1) Monitoring:持續監控Redis master或slave實例的運行狀況是否符合預期
2) Notification:若被監控的Redis實例運行異常,sentinel會經過API通知外界(人或程序)
3) Automation failover:若master實例故障,sentinel會從新選主並啓動自動故障切換:選擇slave-priority最小的那個slave實例並將其提高爲master,同時修改其它slave的配置,使其master配置項指向新的master,當old master恢復重啓後,會自動降級爲new master的slave。最後,根據配置,Redis Sentinel還會將新的master地址通知給當前正在訪問Redis的應用程序。運維
2. Redis Sentinel部署
Sentinel做爲一個分佈式系統工具,建議多機房多機部署。tcp
2.1 sentinel配置文件
每一個sentinel實例主要有6個配置項,按Redis集羣的實際部署狀況進行配置便可,示例以下:
分佈式
[plain] view plain copy ide
port 26329 工具
sentinel monitor mymaster 127.0.0.1 6379 2 測試
sentinel down-after-milliseconds mymaster 60000 url
sentinel failover-timeout mymaster 180000 spa
sentinel parallel-syncs mymaster .net
sentinel notification-script <master-name> <script-path>
其中:
port: 指定sentinel的偵聽端口(即與redis server或client創建tcp鏈接的端口)
monitor: 指定sentinel要monitor的redis實例,包括一個redis實例的別名(alias)及redis實例的ip+port,該行最後的數字2表示至少2個setinel實例同時檢測到redis server異常時,纔將redis server的狀態判決爲real fail。也即,若這裏配置爲2,但實際部署中sentinel只部署了1套,則即便redis實例已經掛掉,sentinel也不會給出任何警告。這一點須要特別引發注意。
down-after-milliseconds: 指定sentinel監控到redis實例持續異常多長時間後,會判決其狀態爲down。若實際業務須要sentinel儘快判決出redis實例異常,則該值可適當配小。
failover-timeout: 若sentinel在該配置值內未能完成failover操做(即故障時master/slave自動切換),則認爲本次failover失敗。該配置有4個用途,具體可參考sentinel.conf中的說明,限於篇幅,此處再也不贅述。
parallel-syncs: 指定failover過程當中,同時被sentinel reconfigure的最大slave實例數。因爲reconfigure過程當中,對應的slave會中斷響應客戶端請求,故爲避免全部的slave同時不可用,該值需適當配小。
notification-script: 指定sentinel檢測到master-name指向的實例異常時,調用的報警腳本。該配置項可選,但線上系統建議配置。
2.2 啓動監控系統
配置文件修改完成後,啓動各監控進程便可,例如:
[plain] view plain copy
nohup ./bin/redis-sentinel ./conf/sentinel.conf > ./log/redis-sentinel.log 2>&1 &
2.3 sentinel使用場景實測
爲調研並掌握sentinel用法,我搭建了redis測試環境並作了一系列實驗,下面對實驗狀況作詳細說明。
特別說明:因爲下面的內容可能會涉及到公司內網地址,故爲避免沒必要要的麻煩,文字或截圖出現ip地址的地方作了塗抹,但不影響說明問題。
實驗環境(one master / two slaves / two sentinels):
a. 一個master(slave-priority爲100)部署在ip爲xx.xx.234.67的機器上;
b. 兩個slaves(slave-priority分別爲90/100)的均部署在ip爲xx.xx.234.49的機器上;
c. 啓用兩個sentinel進程監控redis集羣狀態
作了6種case的測試,結果說明以下:
Case1: 依次啓動master進程及2個slave進程後,再啓動2個sentinel進程,sentinel能夠正常識別出主從關係
Case2: 用shutdown命令停掉master,則sentinel自動選slave-priority小的那個slave進程爲new master,同時,自動將另外一個slave進程的master指向該new master
Case3: 在case2基礎上,重啓old master,sentinel會將其降級爲slave,其master指向case2選出的新主
Case4: 將master和2個slave實例的slave-priority配爲互不相同的值,在Case1基礎上,shutdown當前的master,在sentinel已選出新主且reconfigure其它實例使它們指向新主後(從old master異常到觸發sentinel從新選主的時間由用戶經過sentinel.conf的down-after-milliseconds配置項指定),重啓old master,系統最終狀態與Case3一致,即old master已降級爲slave,其master指向sentinel選出的新主。若在sentinel已選出新主但還沒有完成其它實例的reconfigure以前,重啓old master,則整個系統會出現沒法選出new master的異常,詳情見下面Case5的描述。
Case5: 將master和2個slave實例的slave-priority均配爲相同的值,在Case1基礎上,shutdown當前的master,在sentinel已選出新主且reconfigure其它實例使它們指向新主後,重啓old master,系統最終狀態與Case3一致,即old master已降級爲slave,其master指向sentinel選出的新主。在全部slave-priority配置爲相同值的狀況下,sentinel會將各slave實例中runid最小的slave提高爲master(前提是該slave對應的redis.conf中容許其被promote爲master)。與Case4出現的異常狀況相似,若在sentinel選出新主但還沒有完成其它實例的reconfigure以前,重啓old master,會發現sentinel的自動故障切換機制已然凌亂了。
詳細的異常狀況以下所述。
old master部署在ip爲xx.xx.234.67的機器上且port默認爲6379,sentinel切換異常後,對該old master執行info命令輸出以下:
slave-00實例在ip爲xx.xx.234.49的機器上且port配爲6378,sentinel切換異常後,info輸出以下:
slave-01實例在ip爲xx.xx.234.49的機器上(與slave-00同機部署)且port配爲6377,info輸出以下:
從上面3個redis實例的輸出狀況看,3個均認爲本身是slave,整個系統無主!其中,位於xx.xx.234.67的old master(注意上面第1圖的master_host字段)和位於xx.xx.234.49的salve-00(注意上面第2圖的master_host字段)均認爲slave-01爲new master,而位於xx.xx.234.49的slave-01則認爲本身仍然爲slave,認爲old master目前仍是master(注意上面第3圖的master_host字段)。
從sentinel進程日誌看,其沒法選出新主,即sentinel沒法確認兩個master candidates到底哪一個是new master,在兩個實例間頻繁切換:
這種狀況務在實際運維時務必要引發注意!
Case 6: 在系統已進入Case5所示的異常狀態後,shutdown兩個master candidates中的一個實例,sentinel仍然沒法正常選主,直至3個實例所有shutdown,整個系統仍然無主。基本能夠肯定監控系統內部邏輯狀態已經混亂了。
2.4 結論
若master實例故障,則最好等sentinel選出new master且穩定後(選新主並完成切換的時間與配置有關,典型值在1分鐘以內),再重啓old master,避免引起sentinel的誤判,致使整個系統沒法選出new master。