天天看點

哨兵 (sentinal) 機制的工作原理

哨兵 (sentinal) 機制的工作原理

什麼是哨兵機制?

Redis的哨兵(sentinel) 系統用于管理多個 Redis 伺服器,該系統執行以下三個任務:

       監控(Monitoring): 哨兵(sentinel) 會不斷地檢查你的Master和Slave是否運作正常。

       提醒(Notification):當被監控的某個 Redis出現問題時, 哨兵(sentinel) 可以通過 API 向管理者或者其他應用程式發送通知。

      自動故障遷移(Automatic failover):當一個Master不能正常工作時,哨兵(sentinel) 會開始一次自動故障遷移操作,它會将失效Master的其中一個Slave更新為新的Master, 并讓失效Master的其他Slave改為複制新的Master; 當用戶端試圖連接配接失效的Master時,叢集也會向用戶端傳回新Master的位址,使得叢集可以使用Master代替失效Master。

主要功能

哨兵是redis叢集架構中非常重要的一個元件,主要功能如下:

(1)叢集監控,負責監控redis master 和slave程序是否正常工作。

(2)消息通知,如果某個redis執行個體有故障,那麼哨兵負責發送消息作為報警通知給管理者。

(3)故障轉移,如果master node挂掉了,會自動轉移到slave node上。

(4)配置中心,如果故障轉移發生了,通知client用戶端新的master位址。

哨兵(sentinel) 是一個分布式系統,你可以在一個架構中運作多個哨兵(sentinel) 程序,這些程序使用流言協定(gossipprotocols)來接收關于Master是否下線的資訊,并使用投票協定(agreement protocols)來決定是否執行自動故障遷移,以及選擇哪個Slave作為新的Master。

      每個哨兵(sentinel) 會向其它哨兵(sentinel)、master、slave定時發送消息,以确認對方是否”活”着,如果發現對方在指定時間(可配置)内未回應,則暫時認為對方已挂(所謂的”主觀認為當機” Subjective Down,簡稱sdown).

若“哨兵群”中的多數sentinel,都報告某一master沒響應,系統才認為該master"徹底死亡"(即:客觀上的真正down機,Objective Down,簡稱odown),通過一定的vote算法,從剩下的slave節點中,選一台提升為master,然後自動修改相關配置。

      雖然哨兵(sentinel) 釋出為一個單獨的可執行檔案 redis-sentinel ,但實際上它隻是一個運作在特殊模式下的 Redis 伺服器,你可以在啟動一個普通 Redis 伺服器時通過給定 --sentinel 選項來啟動哨兵(sentinel)。

      哨兵(sentinel) 的一些設計思路和zookeeper非常類似

哨兵作為一個哨兵叢集去運作的,互相協同工作。

(1)故障轉移時,判斷一個master node當機了,需要大部分哨兵都同意才行,涉及到分布式選舉問題。

(2)及時部分哨兵節點挂掉了,哨兵叢集還是能正常工作的,因為如果一個作為高可用機制重要組成部分的故障轉移系統本身就是單點,那麼就不靠譜。

核心知識

  • 哨兵至少需要3個執行個體,來保證自己的健壯性。
  • 哨兵+redis主從的部署架構,是不會保證資料零丢失的,隻能保證redis叢集的高可用性
  • 對于哨兵+redis主從這種複雜的部署架構,盡量在測試環境和生産環境,都進行充分的測試和演練。

資料丢失問題

redis哨兵主備切換的資料丢失問題

兩種丢失情況:

  • 異步複制導緻的資料丢失

    因為master->slave的複制是異步的,是以可能有部分資料還沒複制到slave,master就當機了,這些資料就丢失了。

  • 腦裂導緻的資料丢失

    腦裂,也就是說,某個master所在機器突然脫離了正常的網絡,跟其他slave機器不能連接配接,但是實際上master還運作着

    這個時候,叢集中就會出現兩個master。

    此時雖然某個slave被切換成了master,但是可能client還沒來得及切換到新的master,還繼續寫向舊master資料可能就會丢失。

    是以master在恢複的時候,會被作為一個slave挂到新的master上,自己的資料會被清空,從新的master複制資料

解決異步複制和腦裂導緻的資料丢失:

要求至少有1個slave,資料複制和同步的延遲不能超過10秒

如果說一旦所有slave,資料複制和同步的延遲都超過了10秒鐘,那麼這個時候,master就不會再接收任何請求了。

(1)減少異步複制的資料丢失

有了min-slaves-max-lag這個配置,就可以確定說,一旦slave複制資料和ack延時太長,就認為可能master當機後損失的資料太多了,那麼就拒絕寫請求,這樣可以把master當機時由于部分資料未同步到slave導緻的資料丢失降低的可控範圍内

(2)減少腦裂的資料丢失

如果一個master出現了腦裂,跟其他slave丢了連接配接,那麼上面兩個配置可以確定說,如果不能繼續給指定數量的slave發送資料,而且slave超過10秒沒有給自己ack消息,那麼就直接拒絕用戶端的寫請求

這樣腦裂後的舊master就不會接受client的新資料,也就避免了資料丢失

上面的配置就確定了,如果跟任何一個slave丢了連接配接,在10秒後發現沒有slave給自己ack,那麼就拒絕新的寫請求

是以在腦裂場景下,最多就丢失10秒的資料

繼續閱讀