Redis 哨兵模式的原理及其搭建

上古南城發表於2023-11-09

1.Redis哨兵

Redis提供了哨兵(Sentinel)機制來實現主從叢集的自動故障恢復。

1.1.哨兵原理

1.1.1.叢集結構和作用

哨兵的結構如圖:

哨兵的作用如下:

  • 監控:Sentinel 會不斷檢查您的master和slave是否按預期工作。

  • 自動故障恢復:如果master故障,Sentinel會將一個slave提升為master。當故障例項恢復後也以新的master為主。

  • 通知:Sentinel充當Redis客戶端的服務發現來源,當叢集發生故障轉移時,會將最新資訊推送給Redis的客戶端。

1.1.2.叢集監控原理

  • Sentinel基於心跳機制監測服務狀態,每隔1秒向叢集的每個例項傳送ping命令。

  • 主觀下線:如果某sentinel節點發現某例項未在規定時間響應,則認為該例項主觀下線

  • 客觀下線:若超過指定數量(quorum)的sentinel都認為該例項主觀下線,則該例項客觀下線。quorum值最好超過Sentinel例項數量的一半。

1.1.3.叢集故障恢復原理

一旦發現master故障,sentinel需要在salve中選擇一個作為新的master,選擇依據是這樣的:

  • 首先會判斷slave節點與master節點斷開時間長短,如果超過指定值(down-after-milliseconds * 10)則會排除該slave節點。

  • 然後判斷slave節點的slave-priority值,越小優先順序越高,如果是0則永不參與選舉。

  • 如果slave-prority一樣,則判斷slave節點的offset值,越大說明資料越新,優先順序越高。

  • 最後是判斷slave節點的執行id大小,越小優先順序越高。

當選出一個新的master後,該如何實現切換呢?

流程如下:

  • sentinel給備選的slave1節點傳送slaveof no one命令,讓該節點成為master。

  • sentinel給所有其它slave傳送slaveof 192.168.150.101 7002 命令,讓這些slave成為新master的從節點,開始從新的master上同步資料。

  • 最後,sentinel將故障節點標記為slave,當故障節點恢復後會自動成為新的master的slave節點

1.1.4.總結

Sentinel的三個作用是什麼?

  • 監控
  • 故障轉移
  • 通知

Sentinel如何判斷一個redis例項是否健康?

  • 每隔1秒傳送一次ping命令,如果超過一定時間沒有相向則認為是主觀下線
  • 如果大多數sentinel都認為例項主觀下線,則判定服務下線

故障轉移步驟有哪些?

  • 首先選定一個slave作為新的master,執行slaveof no one
  • 然後讓所有節點都執行slaveof 新master
  • 修改故障節點配置,新增slaveof 新master

1.2.搭建哨兵叢集

1.2.1.叢集結構

這裡搭建一個三節點形成的Sentinel叢集,來監管之前的Redis主從叢集。如圖:

三個sentinel例項資訊如下:

節點 IP PORT
s1 192.168.150.101 27001
s2 192.168.150.101 27002
s3 192.168.150.101 27003

1.2.2.準備例項和配置

要在同一臺虛擬機器開啟3個例項,必須準備三份不同的配置檔案和目錄,配置檔案所在目錄也就是工作目錄。

建立三個資料夾,名字分別叫s1、s2、s3:

# 進入/tmp目錄
cd /tmp
# 建立目錄
mkdir s1 s2 s3

如圖:

然後我們在s1目錄建立一個sentinel.conf檔案,新增下面的內容:

port 27001
sentinel announce-ip 192.168.150.101
sentinel monitor mymaster 192.168.150.101 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmp/s1"

解讀:

  • port 27001:是當前sentinel例項的埠
  • sentinel monitor mymaster 192.168.150.101 7001 2:指定主節點資訊
    • mymaster:主節點名稱,自定義,任意寫
    • 192.168.150.101 7001:主節點的ip和埠
    • 2:選舉master時的quorum值

然後將s1/sentinel.conf檔案複製到s2、s3兩個目錄中(在/tmp目錄執行下列命令):

# 方式一:逐個複製
cp s1/sentinel.conf s2
cp s1/sentinel.conf s3
# 方式二:管道組合命令,一鍵複製
echo s2 s3 | xargs -t -n 1 cp s1/sentinel.conf

修改s2、s3兩個資料夾內的配置檔案,將埠分別修改為27002、27003:

sed -i -e 's/27001/27002/g' -e 's/s1/s2/g' s2/sentinel.conf
sed -i -e 's/27001/27003/g' -e 's/s1/s3/g' s3/sentinel.conf

1.2.3.啟動

為了方便檢視日誌,我們開啟3個ssh視窗,分別啟動3個redis例項,啟動命令:

# 第1個
redis-sentinel s1/sentinel.conf
# 第2個
redis-sentinel s2/sentinel.conf
# 第3個
redis-sentinel s3/sentinel.conf

啟動後:

1.2.4.測試

嘗試讓master節點7001當機,檢視sentinel日誌:

檢視7003的日誌:

檢視7002的日誌: