1. 程式人生 > >Redis進階篇3

Redis進階篇3

本章主要介紹redis持久化、主從架構、複製原理、叢集架構、資料分散式儲存原理、哨兵原理、高可用架構.

4、redis哨兵原理和高可用架構

   思考:如果master node死掉了,會怎麼樣?

沒法寫資料,slave node也會沒法用。整個系統不可用了。

解決辦法:使用主備切換(故障轉移)

Master node故障時,自動檢測,並且將某個slave node自動切換成masternode的過程叫做主備切換。實現主備切換使用的技術就是redissentinal node(哨兵)。

    4.1哨兵的介紹

sentinal,中文名是哨兵

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

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

(2)訊息通知,如果某個redis例項有故障,那麼哨兵負責傳送訊息作為報警通知給管理員

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

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

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

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

(2)即使部分哨兵節點掛掉了,哨兵叢集還是能正常工作的。

4.2、哨兵的核心知識

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

(2)哨兵 + redis主從的部署架構,是不會保證資料零丟失的,只能保證

redis叢集的高可  

用性

(3)哨兵節點最好為大於3的奇數例項。

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

哨兵叢集必須部署2個以上節點

如果哨兵叢集僅僅部署了個2個哨兵例項,quorum=1

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

| M1 |-----| R1 |

|S1 |         | S2 |

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

Configuration: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個哨兵都執行著,就可以允許執行故障轉移

但是如果整個M1和S1執行的機器宕機了,那麼哨兵只有1個了,此時就沒有majority來允許執行故障轉移,雖然另外一臺機器還有一個R1,但是故障轉移不會執行

4.4、經典的3節點哨兵叢集

        +----+

         | M1 |

       | S1 |

        +----+

            |

+----+   |    +----+

|R2 |----+----| R3 |

| S2 |             |S3 |

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

Configuration: quorum = 2,majority

如果M1所在機器宕機了,那麼三個哨兵還剩下2個,S2和S3可以一致認為master宕機,然後選舉出一個來執行故障轉移

同時3個哨兵的majority是2,所以還剩下的2個哨兵執行著,就可以允許執行故障轉移

4.5主備切換的過程,可能會導致資料丟失

(1)非同步複製導致的資料丟失

因為master-> slave的複製是非同步的,所以可能有部分資料還沒複製到slave,master就宕機了,此時這些部分資料就丟失了

(2)腦裂導致的資料丟失

腦裂,也就是說,某個master所在機器突然脫離了正常的網路,跟其他slave機器不能連線,但是實際上master還執行著

此時哨兵可能就會認為master宕機了,然後開啟選舉,將其他slave切換成了master

這個時候,叢集裡就會有兩個master,也就是所謂的腦裂

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

因此舊master再次恢復的時候,會被作為一個slave掛到新的master上去,自己的資料會清空,重新從新的master複製資料

4.6、解決非同步複製和腦裂導致的資料丟失

min-slaves-to-write1

min-slaves-max-lag10

要求至少有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秒的資料

4.7哨兵相關機制

1、sdown和odown轉換機制

sdown和odown兩種失敗狀態

sdown是主觀宕機,就一個哨兵如果自己覺得一個master宕機了,那麼就是主觀宕機

odown是客觀宕機,如果quorum數量的哨兵都覺得一個master宕機了,那麼就是客觀宕機

sdown達成的條件很簡單,如果一個哨兵ping一個master,超過了is-master-down-after-milliseconds指定的毫秒數之後,就主觀認為master宕機

sdown到odown轉換的條件很簡單,如果一個哨兵在指定時間內,收到了quorum指定數量的其他哨兵也認為那個master是sdown了,那麼就認為是odown了,客觀認為master宕機

2、哨兵叢集的自動發現機制

哨兵互相之間的發現,是通過redis的pub/sub系統實現的,每個哨兵都會往__sentinel__:hello這個channel裡傳送一個訊息,這時候所有其他哨兵都可以消費到這個訊息,並感知到其他的哨兵的存在

每隔兩秒鐘,每個哨兵都會往自己監控的某個master+slaves對應的__sentinel__:hello channel裡傳送一個訊息,內容是自己的host、ip和runid還有對這個master的監控配置

每個哨兵也會去監聽自己監控的每個master+slaves對應的__sentinel__:hello channel,然後去感知到同樣在監聽這個master+slaves的其他哨兵的存在

每個哨兵還會跟其他哨兵交換對master的監控配置,互相進行監控配置的同步

3、slave配置的自動糾正

哨兵會負責自動糾正slave的一些配置,比如slave如果要成為潛在的master候選人,哨兵會確保slave在複製現有master的資料; 如果slave連線到了一個錯誤的master上,比如故障轉移之後,那麼哨兵會確保它們連線到正確的master上

4、slave->master選舉演算法

如果一個master被認為odown了,而且majority哨兵都允許了主備切換,那麼某個哨兵就會執行主備切換操作,此時首先要選舉一個slave來

會考慮slave的一些資訊

(1)跟master斷開連線的時長

(2)slave優先順序

(3)複製offset

(4)runid

如果一個slave跟master斷開連線已經超過了down-after-milliseconds的10倍,外加master宕機的時長,那麼slave就被認為不適合選舉為master

(down-after-milliseconds* 10) + milliseconds_since_master_is_in_SDOWN_state

接下來會對slave進行排序

(1)按照slave優先順序進行排序,slave priority越低,優先順序就越高

(2)如果slavepriority相同,那麼看replica offset,哪個slave複製了越多的資料,offset越靠後,優先順序就越高

(3)如果上面兩個條件都相同,那麼選擇一個run id比較小的那個slave

5、quorum和majority

每次一個哨兵要做主備切換,首先需要quorum數量的哨兵認為odown,然後選舉出一個哨兵來做切換,這個哨兵還得得到majority哨兵的授權,才能正式執行切換

如果quorum< majority,比如5個哨兵,majority就是3,quorum設定為2,那麼就3個哨兵授權就可以執行切換

但是如果quorum>= majority,那麼必須quorum數量的哨兵都授權,比如5個哨兵,quorum是5,那麼必須5個哨兵都同意授權,才能執行切換

6、configuration epoch

哨兵會對一套redis master+slave進行監控,有相應的監控的配置

執行切換的那個哨兵,會從要切換到的新master(salve->master)那裡得到一個configurationepoch,這就是一個version號,每次切換的version號都必須是唯一的

如果第一個選舉出的哨兵切換失敗了,那麼其他哨兵,會等待failover-timeout時間,然後接替繼續執行切換,此時會重新獲取一個新的configuration epoch,作為新的version號

7、configuraiton傳播

哨兵完成切換之後,會在自己本地更新生成最新的master配置,然後同步給其他的哨兵,就是通過之前說的pub/sub訊息機制

這裡之前的version號就很重要了,因為各種訊息都是通過一個channel去釋出和監聽的,所以一個哨兵完成一次新的切換之後,新的master配置是跟著新的version號的

其他的哨兵都是根據版本號的大小來更新自己的master配置的