三分鐘帶你入門 redis 高可用架構之哨兵

什麼是哨兵?

哨兵(Sentinel)是 redis 的高可用性解決方案,前面咱們講的主從複製它是高可用的基礎,須要人工介入才能完成故障轉移,哨兵能夠解決這個問題,在主從複製狀況下,當主節點發生故障時,哨兵能夠自動的發現故障而且完成故障轉移,實現真正的 redis 高可用。在哨兵集羣中,哨兵會監視全部的 redis 服務器和其餘 sentinel 節點狀態,來保證 redis 的高可用。java

哨兵的搭建

哨兵本質也是一個 redis 服務,只是跟普通的 redis 服務提供了不同的功能。哨兵是一個分佈式架構,由於你要保證 redis 高可用,首先須要保證本身高可用,因此若是咱們須要搭建哨兵的話,最少須要部署三個實例,最好是奇數個,由於在後續的故障轉移中會涉及到投票。redis

哨兵的配置文件咱們能夠在 redis 的 GitHub 項目下下載,在項目下有一個叫作 sentinel.conf 的文件,可使用它做爲咱們哨兵的配置模板,固然你也可使用 redis.conf 配置文件,只須要添加哨兵相關配置就行了。算法

哨兵相關的配置項很少,主要有如下幾個配置項:服務器

// 端口號,默認是 redis 實例+20000,因此咱們沿用這個規則就行了
port 26379 
// 是否守護進程運行
daemonize yes 
// 日誌存放的位置,這個很是重要,經過日誌能夠查看故障轉移的過程
logfile "26379.log" 
// 監視一個名爲 mymaster(自定義) 的 redis 主服務器, 這個主服務器的 IP 地址爲 127.0.0.1 , 端口號爲 6379 , 
// 最後面的 2 表明着至少有兩個哨兵認爲主服務器出現故障纔會進行故障轉移,不然認定主服務未失效
sentinel monitor mymaster 127.0.0.1 6379 2 
// 哨兵判斷服務器失效的響應時間,超過這個時間未接收到服務器的迴應,就認爲該服務器失效了
sentinel down-after-milliseconds mymaster 30000 
// 完成故障轉移以後,最多多少個從服務器能夠同時發起數據複製,數字越小,說明完成所有從服務數據複製的時間越長
// 數字越大,對主服務器的壓力就變大了
sentinel parallel-syncs mymaster 1 
// 故障轉移超時時間
sentinel failover-timeout mymaster 180000
複製代碼

對於每一個 Sentinel 實例配置除了 port 和 logfile 不一樣以外,其餘配置項都是同樣的。修改好配置後,咱們可使用 ./redis-sentinel sentinel.conf 命令來啓動哨兵,命令跟 redis 實例啓動差很少,由於哨兵也是 redis 實例,因此咱們可使用 ./redis-cli -p 26379 info sentinel 命令查看當前的哨兵信息,以下圖所示:微信

哨兵信息

問題:如何在只配置 master 服務器的狀況下,發現從服務器和其餘 Sentinel ?架構

從服務器的發現,Sentinel 能夠經過詢問主服務器來獲取從服務器的信息,對於發現其餘 Sentinel 節點,則經過發佈與訂閱功能實現,經過向頻道 sentinel:hello 發送信息來實現的,主要有如下兩步:分佈式

一、每一個 Sentinel 每 2 秒會經過發佈與訂閱功能向全部的主服務和從服務器的 sentinel:hello 頻道發送一條信息, 信息中包含了 Sentinel 的 IP 地址、端口號和運行 ID (runid)學習

二、每一個 Sentinel 都訂閱了被它監視的全部主服務器和從服務器的 sentinel:hello 頻道, 查找以前未出現過的 sentinel (looking for unknown sentinels)。 當一個 Sentinel 發現一個新的 Sentinel 時, 它會將新的 Sentinel 添加到一個列表中, 這個列表保存了 Sentinel 已知的, 監視同一個主服務器的全部其餘 Sentinelspa

哨兵故障轉移原理

故障轉移是哨兵的主要工做,這背後的實現邏輯也是很是的複雜,具體的實現邏輯還請查看相關書籍,我對哨兵的故障轉移總結了如下三點:日誌

一、監聽服務器

每一個 Sentinel 節點每隔 1 秒對主節點、從節點、其餘 Sentinel 節點發送 ping 命令作心跳檢測,來判斷服務器的狀態。

節點也會對 Sentinel 進行相應的回覆,在這些回覆中,如下三種回覆是有效回覆:

  • 返回 +PONG
  • 返回 -LOADING
  • 返回 -MASTERDOWN

若是節點在哨兵配置文件設置的 master-down-after-milliseconds 選項的值內,一直沒有哪怕一次有效回覆,那麼 Sentinel 會把該服務器標記爲下線狀態,咱們把這種下線稱爲主觀下線,也就是說只有這個 sentinel 認爲該服務器是下線狀態。

若是被主觀下線的服務器是主服務器時,sentinel 爲了確認這個主服務器是否真的下線,該 Sentinel 會向其餘的一樣監聽主服務器的 Sentinel 進行詢問,看他們是否也認爲主服務器進入下線狀態,當有足夠多的 Sentinel 都認爲主服務器下線時,該 Sentinel 會將主服務器判斷爲客觀下線,這是真正的下線了,而且會對它進行故障轉移操做。

二、選舉 Sentinel 節點完成轉移任務

故障轉移並非全部的 sentinel 共同完成,而是選舉出一臺 sentinel 節點做爲領導者來完成此次故障轉移,因此當主服務器被標記爲客觀下線時,sentinel 之間就會經過 Raft 算法選舉出一個領導者來完成故障轉移工做。redis 選舉領頭的 sentinel 的規則和方法大體以下:

  • 全部在線的 sentinel 都有資格被選爲領導者,也就是說每一個 sentinel 都有成爲領導者的機會
  • 當 sentinel 標記主服務器爲主觀下線時,會向其餘 Sentinel 節點發送 sentinel is-master-down-by-addr 命令, 要求將本身設置爲領導者
  • 收到命令的 Sentinel 節點,採用先到先得的規則,若是沒有贊成過其餘 Sentinel 節點的 sentinel is-master-down-by-addr 命令,將贊成該請求,不然拒絕
  • 若是該 Sentinel 節點發現本身的票數已經超過半數,那麼它將成爲領導者
  • 若是在規定時間內,沒有選舉出 sentinel 領導者,那麼將在一段時間後再次選舉,知道選出 sentinel 領導者爲止。

三、選舉新 master 服務器完成故障轉移

選舉出來的 sentinel 領導者將完成剩下的故障轉移工做,故障轉移主要有如下三步:

一、挑選出新的主服務器

在已下線的主服務器的全部從服務器中,挑選出一個從服務器,並將其轉換爲主服務器,選擇新的主服務器的規則以下:

  • 在失效主服務器屬下的從服務器當中, 那些被標記爲主觀下線、已斷線、或者最後一次回覆 PING 命令的時間大於五秒鐘的從服務器都會被淘汰
  • 在失效主服務器屬下的從服務器當中, 那些與失效主服務器鏈接斷開的時長超過 down-after 選項指定的時長十倍的從服務器都會被淘汰
  • 在經歷了以上兩輪淘汰以後剩下來的從服務器中, 選出複製偏移量(replication offset)最大的那個從服務器做爲新的主服務器; 若是複製偏移量不可用, 或者從服務器的複製偏移量相同, 那麼帶有最小運行 ID 的那個從服務器成爲新的主服務器

對挑選出來的從服務器執行 slaveof no one 命令,使其成爲主節點。

二、修改其餘從服務器的複製目標

當新的主服務器出現後,sentinel 的領導者下一步須要作的就是,讓其餘從服務器去複製新的主服務器,經過向其餘從服務器發送 slaveof new_master port 命令來完成,複製規則和配置文件的 parallel-syncs 參數有關

三、將舊的主服務器變成從服務器 故障轉移操做最後要作的就是將已下線的主服務器設置爲新的主服務的從服務器,並保持對其關注,等它恢復後命令它去複製新的主節點。

上面就是 redis 哨兵的一些知識,但願看完以後你有所收穫。

最後

目前互聯網上不少大佬都有 Redis 系列教程,若有雷同,請多多包涵了。原創不易,碼字不易,還但願你們多多支持。若文中有所錯誤之處,還望提出,謝謝。

歡迎掃碼關注微信公衆號:「平頭哥的技術博文」,和平頭哥一塊兒學習,一塊兒進步。

平頭哥的技術博文
相關文章
相關標籤/搜索