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


什么是哨兵?

哨兵(Sentinel)是 redis 的高可用性解決方案,前面我們講的主從復制它是高可用的基礎,需要人工介入才能完成故障轉移,哨兵可以解決這個問題,在主從復制情況下,當主節點發生故障時,哨兵可以自動的發現故障並且完成故障轉移,實現真正的 redis 高可用。在哨兵集群中,哨兵會監視所有的 redis 服務器和其他 sentinel 節點狀態,來保證 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 發送信息來實現的,主要有以下兩步:

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

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

哨兵故障轉移原理

故障轉移是哨兵的主要工作,這背后的實現邏輯也是非常的復雜,具體的實現邏輯還請查看相關書籍,我對哨兵的故障轉移總結了以下三點:

1、監聽服務器

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

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

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

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

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

2、選舉 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 領導者為止。

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

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

1、挑選出新的主服務器

在已下線的主服務器的所有從服務器中,挑選出一個從服務器,並將其轉換為主服務器,選擇新的主服務器的規則如下:

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

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

2、修改其他從服務器的復制目標

當新的主服務器出現后,sentinel 的領導者下一步需要做的就是,讓其他從服務器去復制新的主服務器,通過向其他從服務器發送 slaveof new_master port 命令來完成,復制規則和配置文件的 parallel-syncs 參數有關

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

上面就是 redis 哨兵的一些知識,希望看完之后你有所收獲。

最后

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

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

平頭哥的技術博文


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM