實際上,一旦多個實例組成了哨兵集羣,即便有哨兵實例出現故障掛掉了,其餘哨兵還能繼續協做完成主從庫切換的工做,包括斷定主庫是否是處於下線狀態,選擇新主庫,以及通知從庫和客戶端。網絡
哨兵之間的相互發現ide
哨兵實例之間能夠相互發現,要歸功於 Redis 提供的 pub/sub 機制,也就是發佈 / 訂閱機制。blog
哨兵將本身的鏈接信息 (ip, port) 發佈到主庫上, 其它哨兵訂閱事件
本身編寫的應用程序也能夠經過 Redis 進行消息的發佈和訂閱ip
Redis 會以頻道的形式,對這些消息進行分門別類的管理同步
所謂的頻道,實際上就是消息的類別。當消息類別相同時,它們就屬於同一個頻道。反之,就屬於不一樣的頻道。只有訂閱了同一個頻道的應用,才能經過發佈的消息進行信息交換。it
在主從集羣中,主庫上有一個名爲「__sentinel__:hello」的頻道,不一樣哨兵就是經過它來相互發現,實現互相通訊的。ast
哨兵除了彼此之間創建起鏈接造成集羣外,還須要和從庫創建鏈接。這是由於,在哨兵的監控任務中,它須要對主從庫都進行心跳判斷,並且在主從庫切換完成後,它還須要通知從庫,讓它們和新主庫進行同步。class
哨兵如何發現從庫 ip, port集羣
這是由哨兵向主庫發送 INFO 命令來完成的。
哨兵也和客戶端鏈接:
主從庫切換後,客戶端也須要知道新主庫的鏈接信息,才能向新主庫發送請求操做。因此,哨兵還須要完成把新主庫的信息告訴客戶端這個任務。
實際使用哨兵時要求,客戶端可以獲取到哨兵集羣在監控、選主、切換這個過程當中發生的各類事件。
從本質上說,哨兵就是一個運行在特定模式下的 Redis 實例,只不過它並不服務請求操做,只是完成監控、選主和通知的任務。因此,每一個哨兵實例也提供 pub/sub 機制,客戶端能夠從哨兵訂閱消息。哨兵提供的消息訂閱頻道有不少,不一樣頻道包含了主從庫切換過程當中的不一樣關鍵事件。
讓客戶端從哨兵這裏訂閱消息:
客戶端讀取哨兵的配置文件後,能夠得到哨兵的地址和端口,和哨兵創建網絡連
在客戶端執行訂閱命令,來獲取不一樣的事件消息
// 訂閱「全部實例進入客觀下線狀態的事件」: SUBSCRIBE +odown // 訂閱全部的事件 PSUBSCRIBE *
當哨兵把新主庫選擇出來後,客戶端就會看到下面的 switch-master 事件。這個事件表示主庫已經切換了,新主庫的 IP 地址和端口信息已經有了。這個時候,客戶端就能夠用這裏面的新主庫地址和端口進行通訊了。
switch-master
判斷主庫下線的過程:
任何一個實例只要自身判斷主庫「主觀下線」後,就會給其餘實例發送 is-master-down-by-addr 命令。接着,其餘實例會根據本身和主庫的鏈接狀況,作出 Y 或 N 的響應,Y 至關於同意票,N 至關於反對票。
一個哨兵得到了仲裁所需的同意票數後,就能夠標記主庫爲「客觀下線」。這個所需的同意票數是經過哨兵配置文件中的 quorum 配置項設定的。例如,如今有 5 個哨兵,quorum 配置的是 3,那麼,一個哨兵須要 3 張同意票,就能夠標記主庫爲「客觀下線」了。這 3 張同意票包括哨兵本身的一張同意票和另外兩個哨兵的同意票。
此時,這個哨兵就能夠再給其餘哨兵發送命令,代表但願由本身來執行主從切換,並讓全部其餘哨兵進行投票。這個投票過程稱爲「Leader 選舉」。由於最終執行主從切換的哨兵稱爲 Leader,投票過程就是肯定 Leader。
任何一個想成爲 Leader 的哨兵,要知足兩個條件:
拿到半數以上的同意票
拿到的票數同時還須要大於等於哨兵配置文件中的 quorum 值
以 3 個哨兵爲例,假設此時的 quorum 設置爲 2,那麼,任何一個想成爲 Leader 的哨兵只要拿到 2 張同意票,就能夠了。
若是 S3 沒有拿到 2 票 Y,那麼這輪投票就不會產生 Leader。哨兵集羣會等待一段時間(也就是哨兵故障轉移超時時間的 2 倍),再從新選舉。這是由於,哨兵集羣可以進行成功投票,很大程度上依賴於選舉命令的正常網絡傳播。若是網絡壓力較大或有短時堵塞,就可能致使沒有一個哨兵能拿到半數以上的同意票。因此,等到網絡擁塞好轉以後,再進行投票選舉,成功的機率就會增長。
須要注意的是,若是哨兵集羣只有 2 個實例,此時,一個哨兵要想成爲 Leader,必須得到 2 票,而不是 1 票。因此,若是有個哨兵掛掉了,那麼,此時的集羣是沒法進行主從庫切換的。所以,一般咱們至少會配置 3 個哨兵實例。這一點很重要,你在實際應用時可不能忽略了。
支持哨兵集羣的這些關鍵機制:
基於 pub/sub 機制的哨兵集羣組成過程;
基於 INFO 命令的從庫列表,這能夠幫助哨兵和從庫創建鏈接;
基於哨兵自身的 pub/sub 功能,這實現了客戶端和哨兵之間的事件通知。
最後,我想再給你分享一個經驗:要保證全部哨兵實例的配置是一致的,尤爲是主觀下線的判斷值 down-after-milliseconds。咱們曾經就踩過一個「坑」。當時,在咱們的項目中,由於這個值在不一樣的哨兵實例上配置不一致,致使哨兵集羣一直沒有對有故障的主庫造成共識,也就沒有及時切換主庫,最終的結果就是集羣服務不穩定。因此,你必定不要忽略這條看似簡單的經驗。