Sentinel 簡介
Redis 的 Sentinel 系統用于管理多個 redis 伺服器(instance), 該系統執行以下三個任務:
監控(Monitoring): Sentinel 會不斷地檢查你的主伺服器和從伺服器是否運作正常。
提醒(Notification): 當被監控的某個 Redis 伺服器出現問題時, Sentinel 可以通過API 向管理者或者其他應用程式發送通知。
自動故障遷移(Automatic failover): 當一個主伺服器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會将失效主伺服器的其中一個從伺服器更新為新的主伺服器, 并讓失效主伺服器的其他從伺服器改為複制新的主伺服器; 當用戶端試圖連接配接失效的主伺服器時, 叢集也會向用戶端傳回新主伺服器的位址, 使得叢集可以使用新主伺服器代替失效伺服器。
Redis Sentinel 是一個分布式系統, 你可以在一個架構中運作多個 Sentinel 程序(progress), 這些程序使用流言協定(gossip protocols)來接收關于主伺服器是否下線的資訊, 并使用投票協定(agreement protocols)來決定是否執行自動故障遷移,以及選擇哪個從伺服器作為新的主伺服器。
雖然 Redis Sentinel 釋出為一個單獨的可執行檔案 redis-sentinel , 但實際上它隻是一個運作在特殊模式下的 Redis 伺服器, 你可以在啟動一個普通 Redis 伺服器時通過給定 --sentinel 選項來啟動Redis Sentinel 。
主觀下線和客觀下線
1. 主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個 Sentinel 執行個體對伺服器做出的下線判斷。
2. 客觀下線(Objectively Down, 簡稱 ODOWN)指的是多個 Sentinel 執行個體在對同一個伺服器做出 SDOWN 判斷, 并且通過 SENTINEL is-master-down-by-addr 指令互相交流之後, 得出的伺服器下線判斷。
客觀下線條件隻适用于主伺服器: 對于任何其他類型的 Redis 執行個體, Sentinel 在将它們判斷為下線前不需要進行協商, 是以從伺服器或者其他 Sentinel 永遠不會達到客觀下線條件。
隻要一個 Sentinel 發現某個主伺服器進入了客觀下線狀态, 這個 Sentinel 就可能會被其他 Sentinel 推選出, 并對失效的主伺服器執行自動故障遷移操作。
每個Sentinel執行個體都執行的定時任務
1. 每個 Sentinel 以每秒鐘一次的頻率向它所知的主伺服器、從伺服器以及其他 Sentinel 執行個體發送一個 PING 指令。
2. 如果一個執行個體(instance)距離最後一次有效回複 PING 指令的時間超過 down-after-milliseconds 選項所指定的值, 那麼這個執行個體會被 Sentinel 标記為主觀下線。 一個有效回複可以是: +PONG 、 -LOADING 或者 -MASTERDOWN 。
3. 如果一個主伺服器被标記為主觀下線, 那麼正在監視這個主伺服器的所有 Sentinel 要以每秒一次的頻率确認主伺服器的确進入了主觀下線狀态。
4. 如果一個主伺服器被标記為主觀下線, 并且有足夠數量的 Sentinel (至少要達到配置檔案指定的數量)在指定的時間範圍内同意這一判斷, 那麼這個主伺服器被标記為客觀下線。
5. 在一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有主伺服器和從伺服器發送 INFO 指令。 當一個主伺服器被 Sentinel 标記為客觀下線時, Sentinel 向下線主伺服器的所有從伺服器發送 INFO 指令的頻率會從 10 秒一次改為每秒一次。
6. 當沒有足夠數量的 Sentinel 同意主伺服器已經下線, 主伺服器的客觀下線狀态就會被移除。 當主伺服器重新向 Sentinel 的 PING 指令傳回有效回複時, 主伺服器的主管下線狀态就會被移除。
Sentinel API
有兩種方式可以與Sentinel進行通訊:指令、釋出與訂閱。
Sentinel指令
PING :傳回 PONG 。
SENTINEL masters :列出所有被監視的主伺服器,以及這些主伺服器的目前狀态;
SENTINEL slaves <master name> :列出給定主伺服器的所有從伺服器,以及這些從伺服器的目前狀态;
SENTINEL get-master-addr-by-name <master name> : 傳回給定名字的主伺服器的 IP 位址和端口号。 如果這個主伺服器正在執行故障轉移操作, 或者針對這個主伺服器的故障轉移操作已經完成, 那麼這個 指令傳回新的主伺服器的 IP 位址和端口号;
SENTINEL reset <pattern> : 重置所有名字和給定模式 pattern 相比對的主伺服器。 pattern 參數是一個 Glob 風格的模式。 重置操作清楚主伺服器目前的所有狀态, 包括正在執行中的故障轉移, 并移除目前已經發現和關聯的, 主伺服器的所有從伺服器和 Sentinel ;
SENTINEL failover <master name> : 當主伺服器失效時, 在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移。
用戶端可以通過SENTINEL get-master-addr-by-name <master name>擷取目前的主伺服器IP位址和端口号,以及SENTINEL slaves <master name>擷取所有的Slaves資訊
釋出與訂閱資訊
用戶端可以将 Sentinel 看作是一個隻提供了訂閱功能的 Redis 伺服器: 你不可以使用 PUBLISH 指令向這個伺服器發送資訊, 但你可以用 SUBSCRIBE 指令或者 PSUBSCRIBE 指令, 通過訂閱給定的頻道來擷取相應的事件提醒。
一個頻道能夠接收和這個頻道的名字相同的事件。 比如說, 名為 +sdown 的頻道就可以接收所有執行個體進入主觀下線(SDOWN)狀态的事件。
通過執行 PSUBSCRIBE * 指令可以接收所有事件資訊。
+switch-master <master name> <oldip> <oldport> <newip> <newport> :配置變更,主伺服器的 IP 和位址已經改變。 這是絕大多數外部使用者都關心的資訊。
可以看出,我們使用Sentinel指令和釋出訂閱兩種機制就能很好的實作和用戶端的內建整合:
使用get-master-addr-by-name和slaves指令可以擷取目前的Master和Slaves的位址和資訊;而當發生故障轉移時,即Master發生切換,可以通過訂閱的+switch-master事件獲得最新的Master資訊。
*PS:更多Sentinel的可訂閱事件參見官方文檔。
sentinel.conf中的notification-script
在sentinel.conf中可以配置多個sentinel notification-script <master name> <shell script-path>, 如sentinel notification-script mymaster ./check.sh
這個是在群集failover時會觸發執行指定的腳本。腳本的執行結果若為1,即稍後重試(最大重試次數為10);若為2,則執行結束。并且腳本最大執行時間為60秒,逾時會被終止執行。
PS:目前會存在該腳本被執行多次的問題,查找資料有人解釋是:
腳本分為兩個級别, SENTINEL_LEADER 和 SENTINEL_OBSERVER ,前者僅由領頭 Sentinel 執行(一個 Sentinel),而後者由監視同一個 master 的所有 Sentinel 執行(多個 Sentinel)。