超全面Redis分散式高可用方案:哨兵機制

ITPUB社群 發表於 2022-12-01
Redis


超全面Redis分散式高可用方案:哨兵機制

開發工作中對於分散式快取高可用方案(搭建 Redis 快取高可用方案),Redis 主從架構下是如何保證高可用的呢?

我們知道 Redis Sentinel 是一個分散式系統,為 Redis 提供高可用性解決方案。那 Redis 服務部署的哨兵模式主要原理是什麼,又解決了什麼問題呢,於是利用時間將相關問題做了整理,相信看完這篇文章,你也可以去給別人做技術分享了。O(∩_∩)O 哈哈~

0. 問題鋪墊

在討論哨兵模式之前,我們先來看一個應用問題:Redis服務主機當機

實際使用過程中,會出現master當機的情況(這樣會導致沒有寫服務,只有讀服務)。那我們要保證服務的可用,就需要從其他salve節點中選取一個來作為master節點,來繼續提供服務能力。


那主要的動作抽象下:

  • 將當機的master下線

  • 找一個slave作為master

  • 通知所有的slave連線新的master

  • 全量資料或者部分資料同步


其中存在幾個問題:

  • 誰來確認master當機?(假如僅僅是網路抖動了一下,就把我宕掉麼?)

  • 如何從slave中找一個master代替,誰來找?怎麼找?有什麼依據?

  • 修改配置後,原始的主恢復了怎麼辦?


其實引入哨兵機制,就可以很好的解決上述問題。

超全面Redis分散式高可用方案:哨兵機制

哨兵-Redis叢集

1. 什麼是哨兵?

Sentinel(哨兵)是Redis 的高可用性解決方案:由一個或多個Sentinel 例項組成的Sentinel 系統可以監視任意多個主服務,以及這些主伺服器屬下的所有從服務,並在被監視的主服務進入下線(不可服務)狀態時,自動將下線主伺服器屬下的某個從伺服器升級為新的主伺服器。

總結一下哨兵的作用:

  • 叢集監控

   不斷的檢查master和slave是否正常執行(master存活檢測、master與slave執行情況檢測)

  • 訊息通知

   當被監控的伺服器出現問題時,向其他哨兵、客戶端傳送通知

  • 自動故障轉移

   斷開故障master與slave的連線,選取一個slave作為新master,將其他slave連線到新的master並告知客戶端新的伺服器地址。

注意:哨兵也是一臺Redis伺服器,只是不提供資料服務;通常哨兵配置的數量為單數。

2. 哨兵的工作原理

下面主要針對哨兵在進行故障轉移過程中經歷的三個階段分別進行闡述。

2.1. 叢集監控

step1:哨兵1連線到Redis叢集

  • 傳送info命令到master,並建立cmd連線;

  • 哨兵端儲存哨兵狀態(SentinelStatus),儲存所有哨兵狀態,主節點和從節點的資訊;master端會記錄 redis 例項的資訊(SentinelRedisInstance);

  • 哨兵根據master中獲取的每個slave資訊,去連線每個slave,傳送同樣也是info命令。

超全面Redis分散式高可用方案:哨兵機制

叢集監控


step2:哨兵2加入進來後

  • 同樣會傳送info命令到master節點,並建立cmd連線;

  • 發現master中存在其他哨兵節點的資訊,哨兵2中儲存哨兵資訊(區別與哨兵1的是它儲存了哨兵1和哨兵2的2個哨兵節點資訊);

  • 為了每個哨兵的資訊都一致它們之間建立了一個釋出訂閱。為了哨兵之間的資訊長期對稱它們之間也會互發 ping 命令。

超全面Redis分散式高可用方案:哨兵機制

叢集監控


step3:哨兵3加入後

  • 同樣進行哨兵1、2的動作,會傳送info命令到master節點,並建立cmd連線;

  • 為了保證哨兵1-哨兵2之間的資訊是同步的,建立了一個釋出訂閱的一個佇列(可以互發ping命令)

超全面Redis分散式高可用方案:哨兵機制

叢集監控


小小總結一下:

  • Sentinel會向master、slave以及其他Sentinel獲取狀態;

  • Sentinel之間會組建“對應頻道”,大家一起釋出資訊、訂閱資訊、收資訊、同步資訊等。

2.2. 訊息通知

1)Sentinel節點會透過master/slave 節點建立的cmd連線獲取其工作狀態

2)Sentinel收到反饋結果之後,會在哨兵內部進行資訊的互通


超全面Redis分散式高可用方案:哨兵機制

訊息通知

2.3. 故障轉移

關於故障轉移,嚴格來講可劃分兩個步驟:故障判定故障轉移

Q1:如何判斷一個節點出現故障?

  • 哨兵會一直給主節點傳送 publish sentinel:hello

直到主節點故障,哨兵報出 sdown,同時此哨兵還會向其他哨兵釋出訊息說這個主節點掛了。傳送的指令是 sentinel is-master-down-by-address-port。

  • 其餘的哨兵接收到指令後,主節點掛了嗎?讓我去看看到底掛沒掛。傳送的資訊也是 hello。

其餘的哨兵也會傳送他們收到的資訊並且傳送指令 sentinel is-master-down-by-address-port 到自己的內網,確認一下第一個傳送 sentinel is-master-down-by-address-port 的哨兵說你說的對,這個傢伙確實掛了。

  • 當所有人都認為主節點掛了後就會修改其狀態為 odown。

當一個哨兵認為主節點掛了標記的是 sdown,當半數哨兵都認為掛了其標記的狀態是 odown。

一個哨兵認為master節點掛了稱為主觀下線(sdown),超半數哨兵認為master節點掛了則稱為客觀下線(odown)。


超全面Redis分散式高可用方案:哨兵機制

Q2:如何進行故障轉移?

1)首先,哨兵選舉出哨兵Leader去處理故障轉移

此時選舉方式應用的是Raft協議,這個之前有過介紹,感興趣的同學可以移步瞭解:一致性演算法Raft 簡易入門

2)其次,哨兵Leader從所有的slave節點找出一個作為master節點

主要的規則:

  • 選擇線上的節點,pass掉已下線的節點;

  • 選擇響應速度快的,pass掉響應慢的節點

  • 選擇與原master斷開時間短的,pass掉斷開時間較長的;

假如以上優先順序均一致,會考慮其他優先原則:

  • 偏移量較大

假如說 slave1 的 offset 為 50,slave2 偏移量為 55,則哨兵就會選擇 slave2 為新的主節點。

  • runid偏大的

這點類似於職場中的論資排輩,也就說根據 runid 的建立時間來判斷,時間早的先上位。

3)資料轉移

  • 新master上任:Sentinel向新的master傳送slaveof no one

  • 其他slave周知:向其他slave傳送slaveof 新master IP埠

3. 總結

Redis 主從複製的作用中有這麼一句話“主從複製是高可用的基石”,那實現高可用必不可少的就是哨兵和叢集。

3.1 Sentinel的作用

  • 叢集監控

不斷的檢查master和slave是否正常執行(master存活檢測、master與slave執行情況檢測)

  • 訊息通知

當被監控的伺服器出現問題時,向其他哨兵、客戶端傳送通知

  • 自動故障轉移

斷開故障master與slave的連線,選取一個slave作為新master,將其他slave連線到新的master並告知客戶端新的伺服器地址。

3.2 Sentinel的工作方式

  • 每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他 Sentinel 例項傳送一個 PING 命令 

  • 如果一個例項(Instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個例項會被 Sentinel 標記為主觀下線。


 若 Master 重新向 Sentinel 的 PING 命令返回有效回覆, Master 的主觀下線狀態就會被移除。

  • 如果一個Master被標記為主觀下線,則正在監視這個Master的所有 Sentinel 要以每秒一次的頻率確認Master的確進入了主觀下線狀態。 

  • 當有足夠數量的 Sentinel(>=配置檔案指定的值)在指定的時間範圍內確認Master的確進入了主觀下線狀態, 則Master會被標記為客觀下線  

若沒有足夠數量的 Sentinel 同意 Master 已經下線, Master 的客觀下線狀態就會被移除。

  • 在一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有Master,Slave傳送 INFO 命令 

  • 當Master被 Sentinel 標記為客觀下線時,Sentinel 向下線的 Master 的所有 Slave 傳送 INFO 命令的頻率會從 10 秒一次改為每秒一次

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2926162/,如需轉載,請註明出處,否則將追究法律責任。