Redis哨兵(Sentinel)模式快速入門

更多內容,歡迎關注微信公衆號:全菜工程師小輝。公衆號回覆關鍵詞,領取免費學習資料。redis

當主服務器宕機後,須要手動把一臺從服務器切換爲主服務器,這就須要人工干預,費事費力,還會形成一段時間內服務不可用。 因此更多時候,咱們優先考慮哨兵(sentinel) 模式。算法

Redis sentinel是Redis高可用實現方案:故障發現、故障自動轉移、配置中心、客戶端通知。從Redis的2.6版本開始提供的,可是當時這個版本的模式是不穩定的,直到Redis的2.8版本之後,這個哨兵模式才穩定下來,在生產環境中,若是想要使用Redis的哨兵模式,也會盡可能使用Redis的2.8版本以後的版本。api

哨兵雖然有一個單獨的可執行文件Redis-sentinel ,但實際上它只是一個運行在特殊模式下的 Redis服務器,你能夠在啓動一個普通Redis服務器時經過給定--sentinel選項來啓動哨兵,哨兵的一些設計思路和zookeeper很是相似。服務器

Redis哨兵模式

sentinel的定時任務

sentinel機制中有三種重要的定時任務。微信

  1. 每10秒每一個sentinel對master和slave執行info

做用:網絡

  • 發現slave節點。
  • 確認主從關係。
  1. 每2秒每一個sentinel經過master節點的channel交換信息(pub/sub)

做用:學習

  • 互相通訊掌握節點的信息和自身信息,能夠感知新加入的sentinel

> 經過master節點的__sentinel__:hello頻道進行交互,全部sentinel訂閱這個頻道並每2秒向該頻道發佈信息設計

  1. 每1秒每一個sentinel對其餘sentinel和master,slave進行ping

做用:代理

  • 心跳檢測

主觀下線和客觀下線

主觀下線

主觀下線:單個sentinel節點對Redis節點通訊失敗的「偏見」。code

這是一種主觀下線。由於在複雜的網絡環境下,這個sentinel與這個master不通,可是若是master與其餘的sentinel都是通的呢?因此是一種「偏見」。

這是依靠的第三種定時:每秒去ping一下週圍的sentinel和Redis。對於slave Redis,可使用這個主觀下線,由於他不須要進行故障轉移;可是對於master Redis,必須使用客觀下線。

客觀下線

客觀下線:全部sentinel節點對master Redis節點失敗「達成共識」(超過quorum個則統一,quorum可配置)。

這是依靠的第二種定時:每兩秒,sentinel之間進行「商量」(一個 sentinel 能夠經過向另外一個 sentinel 發送 SENTINEL is-master-down-by-addr 命令來詢問對方是否定爲給定的服務器已下線。)

對於master redis的下線,必需要達成共識才能夠,由於涉及故障轉移,僅僅依靠一個sentinel判斷是不夠的

領導者選舉

當sentinel集羣須要故障轉移的時候會在集羣中選出Leader執行故障轉移操做。sentinel採用了Raft協議實現了sentinel間選舉Leader的算法,不過也不徹底跟論文描述的步驟一致。sentinel集羣運行過程當中故障轉移完成,全部sentinel又會恢復平等。Leader僅僅是故障轉移操做出現的角色。

選舉流程

  1. 某個sentinel認定master客觀下線的節點後,該sentinel會先看看本身有沒有投過票,若是本身已經投過票給其餘sentinel了,在2倍故障轉移的超時時間本身就不會成爲Leader。至關於它是一個Follower。
  2. 若是該sentinel還沒投過票,那麼它就成爲Candidate。
  3. 和Raft協議描述的同樣,成爲Candidate,sentinel須要完成幾件事情
    3.1 更新故障轉移狀態爲start
    3.2 當前epoch加1,至關於進入一個新term,在sentinel中epoch就是Raft協議中的term。
    3.3 更新本身的超時時間爲當前時間隨機加上一段時間,隨機時間爲1s內的隨機毫秒數。 3.4 向其餘節點發送is-master-down-by-addr命令請求投票。命令會帶上本身的epoch。 3.5 給本身投一票,在sentinel中,投票的方式是把本身master結構體裏的leader和leader_epoch改爲投給的sentinel和它的epoch。
  4. 其餘sentinel會收到Candidate的is-master-down-by-addr命令。若是sentinel當前epoch和Candidate傳給他的epoch同樣,說明他已經把本身master結構體裏的leader和leader_epoch改爲其餘Candidate,至關於把票投給了其餘Candidate。投過票給別的sentinel後,在當前epoch內本身就只能成爲Follower。
  5. Candidate會不斷的統計本身的票數,直到他發現認同他成爲Leader的票數超過一半並且超過它配置的quorum(quorum能夠參考《redis sentinel設計與實現》)。sentinel比Raft協議增長了quorum,這樣一個sentinel可否當選Leader還取決於它配置的quorum。
  6. 若是在一個選舉時間內,Candidate沒有得到超過一半且超過它配置的quorum的票數,本身的此次選舉就失敗了。
  7. 若是在一個epoch內,沒有一個Candidate得到更多的票數。那麼等待超過2倍故障轉移的超時時間後,Candidate增長epoch從新投票。
  8. 若是某個Candidate得到超過一半且超過它配置的quorum的票數,那麼它就成爲了Leader。
  9. 與Raft協議不一樣,Leader並不會把本身成爲Leader的消息發給其餘sentinel。其餘sentinel等待Leader從slave選出master後,檢測到新的master正常工做後,就會去掉客觀下線的標識,從而不須要進入故障轉移流程。

故障轉移過程

  1. 當多個sentinel發現並確認了master有問題
  2. 接着會選舉出一個sentinel做爲領導
  3. 再選舉出一個slave做爲master
  4. 通知其他的slave,新的master是誰
  5. 通知客戶端一個主從的變化
  6. 最後,sentinel會等待舊的master復活,而後將新master成爲slave

那麼,如何選擇「合適」的slave節點呢?

  1. 選擇slave-priority(slave節點優先級,人爲配置)最高的slave節點,若是存在則返回,不存在則繼續。
  2. 其次會選擇複製偏移量最大的slave節點(複製得最完整),若是存在則返回,不存在則繼續
  3. 最後會選擇run_id最小的slave節點(啓動最先的節點)

客戶端實現高可用的基本原理

故障轉移後客戶端沒法感知將沒法保證正常的使用。因此,實現客戶端高可用的步驟以下:

  1. 客戶端獲取sentinel節點集合

Redis哨兵模式

  1. 客戶端經過sentinel get-master-addr-by-name master-name這個api來獲取對應主節點信息

Redis哨兵模式

  1. 客戶端驗證當前獲取的「主節點」是真正的主節點,這樣的目的是爲了防止故障轉移期間主節點的變化

Redis哨兵模式

  1. 客戶端保持和sentinel節點集合的聯繫,即訂閱sentinel節點相關頻道,時刻獲取關於主節點的相關信息

Redis哨兵模式

從上面的模型能夠看出,Redis sentinel客戶端只有在初始化和切換主節點時須要和sentinel進行通訊來獲取主節點信息,因此在設計客戶端時須要將sentinel節點集合考慮成配置(相關節點信息和變化)發現服務。

須要說明的問題

  • 儘量在不一樣物理機上和同一個網絡部署Redis sentinel的全部節點
  • Redis sentinel中的sentinel節點個數應該大於等於3且最好是奇數。(節點數多能夠保證高可用)
  • Redis sentinel中的數據節點和普通數據節點沒有區別。每一個sentinel節點在本質上仍是一個Redis實例,只不過和Redis數據節點不一樣的是,其主要做用是監控Redis數據節點
  • 客戶端初始化時鏈接的是sentinel節點集合,再也不是具體的Redis節點,但sentinel只是配置中心不是代理。

更多內容,歡迎關注微信公衆號:全菜工程師小輝。公衆號回覆關鍵詞,領取免費學習資料。

哎呀,若是個人名片丟了。微信搜索「全菜工程師小輝」,依然能夠找到我

相關文章
相關標籤/搜索