Redis Sentinel 哨兵模式
Redis Sentinel 哨兵模式
1.網路架構
網路結構如下,通過Sentinel監控Master和Slave伺服器:
2.配置啟動
配置檔案如下:
vi /etc/redis-sentinel.conf
port 26379 dir "/tmp" logfile "/var/log/redis/sentinel_20086.log" # 程序守護 daemonize yes # 格式:sentinel <option_name> <master_name> <option_value> # 最後的一個2代表在sentinel叢集中,多少個節點認為master死了,才能真正認為該master不可用 sentinel monitor T1 127.0.0.1 6379 2 # sentinel會向master傳送心跳確認存活 # 如果master在“一定時間範圍”內不迴應PONG 或者是回覆了一個錯誤訊息 # 那麼這個sentinel會主觀地認為這個master已經不可用了 # (subjectively down, 也簡稱為SDOWN)。 # down-after-milliseconds 用來指定這個“一定時間範圍”,單位是毫秒,預設30秒。 sentinel down-after-milliseconds T1 15000 # failover過期時間。 # 當failover開始後,在此時間內仍然沒有觸發任何failover操作,當前sentinel將會認為此次failoer失敗。 # 預設180秒,即3分鐘。 sentinel failover-timeout T1 120000 # 在發生failover時,這個選項指定了最多可以有多少個slave同時對新的master進行同步。 # 這個數字越小,完成failover所需的時間就越長; # 這個數字越大,就意味著越多的slave因為replication而不可用。 # 可以通過將這個值設為 1 來保證每次只有一個slave處於不能處理命令請求的狀態。 sentinel parallel-syncs T1 1 # sentinel 連線密碼驗證 # sentinel auth-pass <master_name> xxxxx # 發生切換之後執行的一個自定義指令碼 # sentinel notification-script <master-name> <script-path> # sentinel client-reconfig-script <master-name> <script-path>
Sentinel 也需要叢集化,以確保:
- 某個/些 Sentinel節點掛了,仍然可以實現Redis主從切換;
- Redis客戶端可以通過任意一個Sentinel讀取/寫入資訊。
啟動Sentinel:
redis-sentinel /path/to/sentinel.conf
啟動後,通過Sentinel的自動識別,配置檔案中會自動加上已識別的Redis叢集節點和Sentinel叢集節點。
3.實現流程
- Sentinel叢集通過配置檔案發現master,啟動時會監控master;
- 向master傳送info命令,獲取其所有slave節點;
- Sentinel叢集向Redis主從伺服器傳送hello資訊(心跳),包括Sentinel本身的ip、埠、id等內容,以此來向其他Sentinel宣告自己的存在;
- Sentinel叢集通過訂閱接收其他Sentinel傳送的hello資訊,以此來發現監視同一個主伺服器的其他Sentinel;叢集之間會互相建立命令連線用於通訊,因為已經有主從伺服器作為傳送和接收hello資訊的中介,Sentinel之間不會建立訂閱連線;
- Sentinel叢集使用ping命令來檢測例項的狀態,如果在指定的時間內(down-after-milliseconds)沒有回覆或則返回錯誤的回覆,那麼該例項被判為下線;
- 當failover主備切換被觸發後,並不會馬上進行,還需要Sentinel中的大多數sentinel授權後才可以進行failover,即進行failover的Sentinel會去獲得指定quorum個的Sentinel的授權,成功後進入ODOWN狀態。如在5個Sentinel中配置了2個quorum,等到2個Sentinel認為master死了就執行failover。
- Sentinel向選為master的slave傳送 SLAVEOF NO ONE 命令,選擇slave的條件是Sentinel首先會根據slaves的優先順序來進行排序,優先順序越小排名越靠前。如果優先順序相同,則檢視複製的下標,哪個從master接收的複製資料多,哪個就靠前。如果優先順序和下標都相同,就選擇程序ID較小的。
- Sentinel被授權後,它將會獲得宕掉的master的一份最新配置版本號(config-epoch),當failover執行結束以後,這個版本號將會被用於最新的配置,通過廣播形式通知其它sentinel,其它的sentinel則更新對應master的配置。
注意:
因為redis採用的是非同步複製,沒有辦法避免資料的丟失。
可以在redis.conf通過以下配置來使得資料不會丟失:
// master最少得有多少個健康的slave存活才能執行寫命令 min-slaves-to-write 1 // 延遲小於min-slaves-max-lag秒的slave才認為是健康的slave min-slaves-max-lag 10
當所有Slave都不符合條件時,master將停止寫入。
4.故障轉移
發生故障轉移時,需要進行領導者選舉。
- sentinel首先會根據slaves的優先順序來進行排序,優先順序越小排名越靠前;
- 如果優先順序相同,則檢視複製的下標,哪個從master接收的複製資料多,哪個就靠前;
- 如果優先順序和下標都相同,就選擇RunID較小的那個;
如果一個redis的slave優先順序配置為0,那麼它將永遠不會被選為master。
故障轉移過程
領導者Sentinel需要將一個salve提升為master,此slave必須為狀態良好,不能處於SDOWN/ODOWN狀態。
- “+failover-triggered”: Leader開始進行failover,此後緊跟著“+failover-state-wait-start”,wait數秒。
- “+failover-state-select-slave”: Leader開始查詢合適的slave
- “+selected-slave”: 已經找到合適的slave
- “+failover-state-sen-slaveof-noone”: Leader向slave傳送“slaveof no one”指令,此時slave已經完成角色轉換,此slave即為master
- “+failover-state-wait-promotition”: 等待其他sentinel確認slave
- “+promoted-slave”:確認成功
- “+failover-state-reconf-slaves”: 開始對slaves進行reconfig操作
- “+slave-reconf-sent”:向指定的slave傳送“slaveof”指令,告知此slave跟隨新的master
- “+slave-reconf-inprog”: 此slave正在執行slaveof + SYNC過程,如過slave收到“+slave-reconf-sent”之後將會執行slaveof操作。
- “+slave-reconf-done”: 此slave同步完成,此後leader可以繼續下一個slave的reconfig操作。迴圈 step 7
- “+failover-end”: 故障轉移結束
- “+switch-master”:故障轉移成功後,各個sentinel例項開始監控新的master。
5.增加和刪除節點
Sentinel會通過PUB/SUB自動識別新增節點。
刪除流程:
- 停止所要刪除的sentinel
- 傳送一個SENTINEL RESET 命令給所有其它的sentinel例項,如果你想要重置指定master上面的sentinel,只需要把 號改為特定的名字,注意,需要一個接一個發,每次傳送的間隔不低於30秒(down-after-milliseconds);
- 檢查一下所有的sentinels是否都有一致的當前sentinel數;