Redis提供了哨兵(Sentinel)機制來實現主從叢集的自動故障恢復。
哨兵的結構如圖:
哨兵的作用如下:
監控:Sentinel 會不斷檢查您的master和slave是否按預期工作。
自動故障恢復:如果master故障,Sentinel會將一個slave提升為master。當故障範例恢復後也以新的master為主。
通知:Sentinel充當Redis使用者端的服務發現來源,當叢集發生故障轉移時,會將最新資訊推播給Redis的使用者端。
Sentinel基於心跳機制監測服務狀態,每隔1秒向叢集的每個範例傳送ping
命令。
主觀下線:如果某sentinel節點發現某範例未在規定時間響應,則認為該範例主觀下線。
客觀下線:若超過指定數量(quorum)的sentinel都認為該範例主觀下線,則該範例客觀下線。quorum值最好超過Sentinel範例數量的一半。
一旦發現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節點
Sentinel的三個作用是什麼?
Sentinel如何判斷一個redis範例是否健康?
故障轉移步驟有哪些?
這裡搭建一個三節點形成的Sentinel叢集,來監管之前的Redis主從叢集。如圖:
三個sentinel範例資訊如下:
節點 | IP | PORT |
---|---|---|
s1 | 192.168.150.101 | 27001 |
s2 | 192.168.150.101 | 27002 |
s3 | 192.168.150.101 | 27003 |
要在同一臺虛擬機器器開啟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
為了方便檢視紀錄檔,我們開啟3個ssh視窗,分別啟動3個redis範例,啟動命令:
# 第1個
redis-sentinel s1/sentinel.conf
# 第2個
redis-sentinel s2/sentinel.conf
# 第3個
redis-sentinel s3/sentinel.conf
啟動後:
嘗試讓master節點7001宕機,檢視sentinel紀錄檔:
檢視7003的紀錄檔:
檢視7002的紀錄檔: