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主從的部署架構,是不會保證資料零丟失的,只能保證
用性
(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配置的