Sentinel(哨兵模式)
經過上期【Redis】主從複製 的學習,
我們知道 主從複製 是為了避免單點故障,將資料儲存在多臺伺服器上的一種機制。
但是主節點只有一個,如果主節點掛掉了,怎麼辦?於是 哨兵模式 誕生了。
哨兵模式可以不時地監控 redis
是否按照預期良好的執行(至少是保證主節點是存在的),若一臺主機出現問題,哨兵會自動將該主機下的某一從機設定為新的主機,並讓其他從機和新主機建立主從關係。
《Redis 設計與實現》哨兵模式介紹:
Sentinel(哨兵)是Redis的高可用性解決方案:由一個或多個 Sentinel 例項組成的Sentinel 系統可以監視任意多個主伺服器,以及這些主伺服器屬下的所有從伺服器,並在監視的主伺服器進入下線狀態時,自動將下線主伺服器屬下的某個從伺服器升級為新主伺服器,然後由新的主伺服器替代已下線的主伺服器繼續處理命令請求。
Sentinel(哨兵) 本質上只是一個執行在特殊模式下的Redis伺服器,但是因為Sentinel(哨兵)並不使用資料庫,所以初始化Sentinel(哨兵)時就不會載入RDB
檔案或者AOF
檔案。
哨兵模式架構模型:
哨兵模式的三個定時任務
- 每10秒每個Sentinel(哨兵)向主從節點傳送info命令,用來獲取最新的主從結構
- 每2秒每個Sentinel(哨兵)通過master節點的channel交換資訊,channel是釋出訂閱的頻道,可以獲取其他哨兵節點的資訊。
- 每1秒Sentinel(哨兵)向與它建立了命令連線的例項(主、從伺服器,其他Sentinel)傳送
PING
命令,用來進行心跳檢測,判斷是否下線
Sentinel(哨兵)與Sentinel 、主伺服器、從伺服器之間的連線
Sentinel(哨兵)在連線主伺服器 或者 從伺服器時,會同時建立命令連線
和 訂閱連線
,命令連線用來 向 主伺服器 和 從伺服器傳送訊息,而訂閱連線用來接收來自主伺服器和從伺服器的資訊。
但是在連線其他Sentinel(哨兵)時只會建立命令連線,而不建立訂閱連線。這是因為Sentinel(哨兵)需要通過接收主伺服器或者從伺服器發來的資訊發現未知的新Sentinel ,而相互已知的Sentinel只要用命令連線來進行通訊就足夠了。
檢測下線狀態
如果只有一個Sentinel(哨兵),那麼可能會又出現單點故障的問題,所以一般設定多個Sentinel(哨兵)來監視。此外,這些不同的哨兵節點應部署在不同的物理機上。
在預設情況下Sentinel(哨兵)會以每秒一次的頻率向與它建立了命令連線的例項(主、從伺服器,其他Sentinel)傳送PING
命令,並通過回覆來判斷例項是否線上。
當Sentinel(哨兵)將一個主伺服器判斷為下線後,為主觀下線。為了確定這個主伺服器是否真的下線了,他會向同樣監視這一主伺服器的其他Sentinel(哨兵)進行詢問,看他們是否也認為主伺服器已經進入了下線狀態。如果多個哨兵(設定一個閾值)都認為 master 異常了,就會認為master 判定為客觀下線,並對主伺服器執行故障轉移操作。
注意,這裡客觀下線是主節點才有的概念;如果從節點和哨兵節點發生故障,被哨兵主觀下線後,不會再有後續的客觀下線和故障轉移操作。
選擇領頭 Sentinel(哨兵)
當主節點被判斷客觀下線以後,各個哨兵節點會進行協商,選舉出一個領導者哨兵節點,並由該領導者節點對其進行故障轉移操作。
監視該主節點的所有哨兵都有可能被選為領導者,選舉使用的演算法是 Raft 演算法。選舉規則:
每個哨兵都詢問其它哨兵,請求對方為自己投票
每個哨兵只投票給第一個請求投票的哨兵,且只能投票一次
首先拿到超過半數投票的哨兵,當選為領導者,發起主從切換
故障轉移
選舉出的領導者哨兵,開始進行故障轉移操作,該操作大體可以分為 3 個步驟:選出新的主伺服器、修改從伺服器的複製目標、將舊的主伺服器變為從伺服器
-
選出新的主伺服器
選擇新的主伺服器,領頭Sentinel 會將已下線主伺服器所有從伺服器儲存到一個列表裡面,按以下規則選出:
-
刪除列表中所有處於下線或者斷線狀態的從伺服器,保證列表中剩餘都是正常線上的。
-
刪除最近5秒內沒有恢復INFO命令的從伺服器,保證列表中剩餘的都是最近成功進行通訊的。
-
刪除與已下線主伺服器斷開時長超過 10 *
down-after-milliseconds
毫秒的從伺服器,保證列表中剩餘的從伺服器儲存的資料都是比較新的。 -
之後根據從伺服器的優先順序,選出優先順序最高的從伺服器。
-
如果有多個相同優先順序的從伺服器,那麼領頭Sentinel選出複製偏移量最大的從伺服器(偏移量越大儲存的資料越新)
-
最後,如果有多個優先順序最高、複製偏移量最大的從伺服器,那麼領頭Sentinel按照執行ID 排序,選擇執行ID 最小的從伺服器
-
-
修改從伺服器的複製目標
當新主伺服器出現後,領頭Sentinel下一步會讓已下線主伺服器屬下所有從伺服器去複製新的主伺服器
-
將舊的主伺服器變為從伺服器
最後要做的是,將舊的主伺服器變為從伺服器。當其重新上線時變為新的主伺服器的從伺服器。
缺點
哨兵仍然沒有解決寫操作無法負載均衡、及儲存能力受到單機限制的問題;這些問題的解決需要使用叢集
本文沒有詳細說明 Sentinel 的初始化過程,詳細請看《Redis 設計與實現》第16章。
參考:
《Redis 設計與實現》