Redis哨兵集羣中哨兵掛了,主從庫還能切換嗎?


           

實際上,一旦多個實例組成了哨兵集羣,即便有哨兵實例出現故障掛掉了,其餘哨兵還能繼續協做完成主從庫切換的工做,包括斷定主庫是否是處於下線狀態,選擇新主庫,以及通知從庫和客戶端。網絡

1,基於 pub/sub 機制的哨兵集羣組成

哨兵之間的相互發現ide

哨兵實例之間能夠相互發現,要歸功於 Redis 提供的 pub/sub 機制,也就是發佈 / 訂閱機制。blog

  • 哨兵將本身的鏈接信息 (ip, port) 發佈到主庫上, 其它哨兵訂閱事件

  • 本身編寫的應用程序也能夠經過 Redis 進行消息的發佈和訂閱ip

  • Redis 會以頻道的形式,對這些消息進行分門別類的管理同步

所謂的頻道,實際上就是消息的類別。當消息類別相同時,它們就屬於同一個頻道。反之,就屬於不一樣的頻道。只有訂閱了同一個頻道的應用,才能經過發佈的消息進行信息交換。it

在主從集羣中,主庫上有一個名爲「__sentinel__:hello」的頻道,不一樣哨兵就是經過它來相互發現,實現互相通訊的。ast

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

哨兵除了彼此之間創建起鏈接造成集羣外,還須要和從庫創建鏈接。這是由於,在哨兵的監控任務中,它須要對主從庫都進行心跳判斷,並且在主從庫切換完成後,它還須要通知從庫,讓它們和新主庫進行同步。class

哨兵如何發現從庫 ip, port集羣

這是由哨兵向主庫發送 INFO 命令來完成的。

哨兵也和客戶端鏈接:

  • 主從庫切換後,客戶端也須要知道新主庫的鏈接信息,才能向新主庫發送請求操做。因此,哨兵還須要完成把新主庫的信息告訴客戶端這個任務。

  • 實際使用哨兵時要求,客戶端可以獲取到哨兵集羣在監控、選主、切換這個過程當中發生的各類事件。

2,基於pub/sub機制的客戶端事件通知

從本質上說,哨兵就是一個運行在特定模式下的 Redis 實例,只不過它並不服務請求操做,只是完成監控、選主和通知的任務。因此,每一個哨兵實例也提供 pub/sub 機制,客戶端能夠從哨兵訂閱消息。哨兵提供的消息訂閱頻道有不少,不一樣頻道包含了主從庫切換過程當中的不一樣關鍵事件。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

讓客戶端從哨兵這裏訂閱消息:

  • 客戶端讀取哨兵的配置文件後,能夠得到哨兵的地址和端口,和哨兵創建網絡連

  • 在客戶端執行訂閱命令,來獲取不一樣的事件消息

// 訂閱「全部實例進入客觀下線狀態的事件」:
SUBSCRIBE +odown

// 訂閱全部的事件
PSUBSCRIBE *

 

當哨兵把新主庫選擇出來後,客戶端就會看到下面的 switch-master 事件。這個事件表示主庫已經切換了,新主庫的 IP 地址和端口信息已經有了。這個時候,客戶端就能夠用這裏面的新主庫地址和端口進行通訊了。

switch-master

   

3.由哪一個哨兵執行主從切換?

判斷主庫下線的過程:

  1. 任何一個實例只要自身判斷主庫「主觀下線」後,就會給其餘實例發送 is-master-down-by-addr 命令。接着,其餘實例會根據本身和主庫的鏈接狀況,作出 Y 或 N 的響應,Y 至關於同意票,N 至關於反對票。

    watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

    一個哨兵得到了仲裁所需的同意票數後,就能夠標記主庫爲「客觀下線」。這個所需的同意票數是經過哨兵配置文件中的 quorum 配置項設定的。例如,如今有 5 個哨兵,quorum 配置的是 3,那麼,一個哨兵須要 3 張同意票,就能夠標記主庫爲「客觀下線」了。這 3 張同意票包括哨兵本身的一張同意票和另外兩個哨兵的同意票。

  2. 此時,這個哨兵就能夠再給其餘哨兵發送命令,代表但願由本身來執行主從切換,並讓全部其餘哨兵進行投票。這個投票過程稱爲「Leader 選舉」。由於最終執行主從切換的哨兵稱爲 Leader,投票過程就是肯定 Leader。

任何一個想成爲 Leader 的哨兵,要知足兩個條件:

  • 拿到半數以上的同意票

  • 拿到的票數同時還須要大於等於哨兵配置文件中的 quorum 值

以 3 個哨兵爲例,假設此時的 quorum 設置爲 2,那麼,任何一個想成爲 Leader 的哨兵只要拿到 2 張同意票,就能夠了。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

若是 S3 沒有拿到 2 票 Y,那麼這輪投票就不會產生 Leader。哨兵集羣會等待一段時間(也就是哨兵故障轉移超時時間的 2 倍),再從新選舉。這是由於,哨兵集羣可以進行成功投票,很大程度上依賴於選舉命令的正常網絡傳播。若是網絡壓力較大或有短時堵塞,就可能致使沒有一個哨兵能拿到半數以上的同意票。因此,等到網絡擁塞好轉以後,再進行投票選舉,成功的機率就會增長。

須要注意的是,若是哨兵集羣只有 2 個實例,此時,一個哨兵要想成爲 Leader,必須得到 2 票,而不是 1 票。因此,若是有個哨兵掛掉了,那麼,此時的集羣是沒法進行主從庫切換的。所以,一般咱們至少會配置 3 個哨兵實例。這一點很重要,你在實際應用時可不能忽略了。

4,總結

支持哨兵集羣的這些關鍵機制:

  • 基於 pub/sub 機制的哨兵集羣組成過程;

  • 基於 INFO 命令的從庫列表,這能夠幫助哨兵和從庫創建鏈接;

  • 基於哨兵自身的 pub/sub 功能,這實現了客戶端和哨兵之間的事件通知。

最後,我想再給你分享一個經驗:要保證全部哨兵實例的配置是一致的,尤爲是主觀下線的判斷值 down-after-milliseconds。咱們曾經就踩過一個「坑」。當時,在咱們的項目中,由於這個值在不一樣的哨兵實例上配置不一致,致使哨兵集羣一直沒有對有故障的主庫造成共識,也就沒有及時切換主庫,最終的結果就是集羣服務不穩定。因此,你必定不要忽略這條看似簡單的經驗。

相關文章
相關標籤/搜索