天天看點

redis主從複制--------哨兵機制

哨兵的介紹

sentinel,中文名是哨兵,

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

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

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

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

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

哨兵本身也是分布式的,作為一個哨兵叢集去運作,互相協同工作

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

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

哨兵的基礎知識

(1)哨兵至少需要3個執行個體,來保證自己的健壯性

(2)哨兵 + redis主從的部署架構,是不會保證資料零丢失的,隻能保證redis叢集的高可用性

(3)對于哨兵 + redis主從這種複雜的部署架構,盡量在測試環境和生産環境,都進行充足的測試和演練

為什麼redis哨兵叢集隻有2個節點無法正常工作?

數量為quorum的哨兵認為節點當機了 那麼節點就當機了。數量為majority的哨兵來進行選舉對應的Master節點。

+----+         +----+

| M1 |---------| R1 |

| S1 |         | S2 |

+----+         +----+

   如果哨兵叢集僅僅部署了個2個哨兵執行個體,quorum=1,master當機,s1和s2中隻要有1個哨兵認為master當機就可以還行切換,同時s1和s2中會選舉出一個哨兵來執行故障轉移。同時這個時候,需要majority,也就是大多數哨兵都是運作的,2個哨兵的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=2),2個哨兵都運作着,就可以允許執行故障轉移

哨兵進行主備切換時候出現的資料丢失問題

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

        因為Master節點的資料要異步進行同步到slave節點上,如果在複制的過程中Master就當機了,就會出現資料丢失的問題。

  • 叢集腦裂導緻的資料丢失

       腦裂的問題就是在資料叢集的狀态下,當Master節點的機器因為網絡的原因(各種原因吧),有quorum數量的數量的機器認為Master已經當機了,然後開始重新選舉産生一個Master節點。舊的Master節點處于一個假死的狀态。Client可以正常的連接配接Master,可以繼續向Master進行寫入資料,不會向新的Master節點進行輸入資料。等網絡恢複(或者什麼别的原因)。舊的的Master重新回歸叢集的時候。舊的Master成為了一個新的Slave,會重新複制新的Master上的資料。但是新的Master上的資料就會缺少。

哨兵主備切換時候資料丢失的問題解決方案

min-slaves-to-write 1

min-slaves-max-lag 10

這兩個的配置的意思是:要求至少有1個slave,資料複制和同步的延遲不能超過10秒,如果說一旦所有的slave,資料複制和同步的延遲都超過了10秒鐘,那麼這個時候,master就不會再接收任何請求了。

上面兩個配置可以減少異步複制和腦裂導緻的資料丢失

哨兵叢集的自動發現機制

        哨兵互相之間的發現,是通過redis的pub/sub系統實作的,每個哨兵都會往__sentinel__:hello這個channel裡發送一個消息,這時候所有其他哨兵都可以消費到這個消息。并感覺到其他的哨兵的存在。每隔兩秒鐘,每個哨兵都會往自己監控的某個master+slaves對應的__sentinel__:hello channel裡發送一個消息,内容是自己的host、ip和runid還有對這個master的監控配置,每個哨兵也會去監聽自己監控的每個master+slaves對應的__sentinel__:hello channel,然後去感覺到同樣在監聽這個master+slaves的其他哨兵的存在。每個哨兵還會跟其他哨兵交換對master的監控配置,互相進行監控配置的同步。

Save--->Master的選舉機制

  如果叢集中的Master認為當機了。哨兵的叢集會進行重新選擇一個新的Master,選擇Master的原則有以下幾個:

  1. 與Master斷開的時長 
  2. 按照slave的優先級進行排序,選擇優先級高的。
  3. 如果優先級相同,看從主節點中複制的資料量(也就是offset的值的大小)
  4. 如果以上兩個值相等話,就選擇一個 runid比較的一個值

哨兵的工作方式

       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 指令傳回有效回複時, 主伺服器的主觀下線狀态就會被移除。

繼續閱讀