超全面分佈式緩存高可用方案:哨兵機制

開發工做中對於分佈式緩存高可用方案(搭建Redis緩存高可用方案),Redis主從架構下是如何保證高可用的呢?redis

咱們知道是應用了哨兵機制來實現。那Redis 服務部署的哨兵模式主要是什麼,又解決了什麼問題呢,因而利用週末時間整理了下,相信看完這篇文章,你也能夠去給別人作技術分享了。O(∩_∩)O哈哈~算法

問題鋪墊

在討論哨兵模式以前,咱們先來看一個應用問題:Redis服務主機宕機緩存

實際使用過程當中,會出現master宕機的狀況(這樣會致使沒有寫服務,只有讀服務)。那咱們要保證服務的可用,就須要從其餘salve節點中選取一個來做爲master節點,來繼續提供服務能力。服務器

那主要的動做抽象下:微信

  • 將宕機的master下線網絡

  • 找一個slave做爲master架構

  • 通知全部的slave鏈接新的master分佈式

  • 全量數據或者部分數據同步spa

其中存在幾個問題:.net

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

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

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

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

哨兵-Redis集羣

什麼是哨兵?

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

總結一下哨兵的做用:

  • 集羣監控

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

  • 消息通知

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

  • 自動故障轉移

   斷開故障master與slave的鏈接,選取一個slave做爲新master,將其餘slave鏈接到新的master並告知客戶端新的服務器地址。

注意:哨兵也是一臺Redis服務器,只是不提供數據服務;一般哨兵配置的數量爲單數。

哨兵的工做原理

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

一、集羣監控

step1:哨兵1鏈接到Redis集羣

  • 發送info命令到master,並創建cmd鏈接;

  • 哨兵端保存哨兵狀態(SentinelStatus),保存全部哨兵狀態,主節點和從節點的信息;master端會記錄 redis 實例的信息(SentinelRedisInstance);

  • 哨兵根據master中獲取的每一個slave信息,去鏈接每一個slave,發送一樣也是info命令。

集羣監控

step2:哨兵2加入進來後

  • 一樣會發送info命令到master節點,並創建cmd鏈接;

  • 發現master中存在其餘哨兵節點的信息,哨兵2中保存哨兵信息(區別與哨兵1的是它保存了哨兵1和哨兵2的2個哨兵節點信息);

  • 爲了每一個哨兵的信息都一致它們之間創建了一個發佈訂閱。爲了哨兵之間的信息長期對稱它們之間也會互發 ping 命令。

集羣監控

step3:哨兵3加入後

  • 一樣進行哨兵一、2的動做,會發送info命令到master節點,並創建cmd鏈接;

  • 爲了保證哨兵1-哨兵2之間的信息是同步的,創建了一個發佈訂閱的一個隊列(能夠互發ping命令)

集羣監控

小結一下:

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

  • Sentinel之間會組建「對應頻道」,你們一塊兒發佈信息、訂閱信息、收信息、同步信息等。

二、消息通知

1)Sentinel節點會經過master/slave 節點創建的cmd鏈接獲取其工做狀態

2)Sentinel收到反饋結果以後,會在哨兵內部進行信息的互通

消息通知

三、故障轉移

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

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)。

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端口

總結

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

一、Sentinel的做用

  • 集羣監控

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

  • 消息通知

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

  • 自動故障轉移

斷開故障master與slave的鏈接,選取一個slave做爲新master,將其餘slave鏈接到新的master並告知客戶端新的服務器地址。

二、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 秒一次改成每秒一次

     


往期熱文推薦:


 

「技術架構精進」專一架構研究,技術分享

 

Thanks for reading!

本文分享自微信公衆號 - 架構精進之路(jiagou_jingjin)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索