一、哨兵的安裝與部署
- 上一篇文章介紹了Redis Sentinel的基本架構,下面將介紹如何安裝和部署Redis Sentinel
- 下面以3個Sentinel節點、1個主節點、2個從節點組成一個Redis Sentinel進行說明,拓撲結構如下圖所示
①部署主節點
- 主節點的地址爲127.0.0.1:6379。配置文件爲/opt/redis/conf/redis-6379.conf,下面列出了部分選項值:
port 6379 daemonize yes logfile 6379.log dbfilename dump-6379.rdb dir /opt/redis/data/
- 啓動主節點:
sudo redis-server /opt/redis/conf/redis-6379.conf
- 檢測主節點是否啓動成功:
redis-cli -h 127.0.0.1 -p 6379 ping
- 此時的拓撲圖如下所示:
②啓動從節點1(127.0.0.1:6380)
- 從節點1的地址爲127.0.0.1:6380。配置文件爲/opt/redis/conf/redis-6380.conf,下面列出了部分選項值:
port 6380 daemonize yes logfile 6380.log dbfilename dump-6380.rdb dir /opt/redis/data/ slaveof 127.0.0.1 6379
- 啓動從節點1:
sudo redis-server /opt/redis/conf/redis-6380.conf
- 檢測從節點1是否啓動成功:
redis-cli -h 127.0.0.1 -p 6380 ping
③啓動從節點2(127.0.0.1:6381)
- 從節點2的地址爲127.0.0.1:6381。配置文件爲/opt/redis/conf/redis-6381.conf,下面列出了部分選項值:
port 6381 daemonize yes logfile 6381.log dbfilename dump-6381.rdb dir /opt/redis/data/ slaveof 127.0.0.1 6379
- 啓動從節點2:
sudo redis-server /opt/redis/conf/redis-6381.conf
- 檢測從節點2是否啓動成功:
redis-cli -h 127.0.0.1 -p 6381 ping
④確認主從關係
- 主節點:查看複製的相關信息,有兩個從節點127.0.0.1:6380和127.0.0.1:6381
redis-cli -h 127.0.0.1 -p 6379 info replication
- 從節點1:查看複製的相關信息,其複製的主節點爲127.0.0.1:6379
redis-cli -h 127.0.0.1 -p 6380 info replication
- 從節點2:查看複製的相關信息,其複製的主節點爲127.0.0.1:6379
redis-cli -h 127.0.0.1 -p 6381 info replication
- 此時的拓撲圖如下所示:
⑤啓動Sentinel節點1(127.0.0.1:26379)
- sentinel節點1的地址爲127.0.0.1:26379。配置文件爲/opt/redis/conf/redis-sentinel-26379.conf,下面列出了部分選項值:
- sentinel節點的默認配置端口爲26379
- sentinel monitor:代表該sentinel節點監控的是127.0.0.1:6379這個主節點,mymaster代表主節點的別名,2代表主節點失敗至少需要2個sentinel節點同一
- 其餘選項在下面介紹
port 26379 daemonize yes logfile 26379.log dir /opt/redis/data/ 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節點1:啓動sentinel節點的方式有兩種,兩種方法的本質是一樣的
# 方法一:通過redis-sentinel命令 sudo redis-sentinel /opt/redis/conf/redis-sentinel-26379.conf # 方法二:通過redis-server加--sentinel參數 sudo redis-server /opt/redis/conf/redis-sentinel-26379.conf --sentinel
啓動Sentinel節點2(127.0.0.1:26380)
- sentinel節點2的地址爲127.0.0.1:26380。配置文件爲/opt/redis/conf/redis-sentinel-26380.conf,下面列出了部分選項值:
port 26380 daemonize yes logfile 26380.log dir /opt/redis/data/ 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節點2:
sudo redis-sentinel /opt/redis/conf/redis-sentinel-26380.conf
啓動Sentinel節點3(127.0.0.1:26381)
- sentinel節點3的地址爲127.0.0.1:26381
- 配置文件爲/opt/redis/conf/redis-sentinel-26381.conf,下面列出了部分選項值:
port 26381 daemonize yes logfile 26381.log dir /opt/redis/data/ 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節點3:
sudo redis-sentinel /opt/redis/conf/redis-sentinel-26381.conf
⑥確認
- Sentinel節點本質上是一個特殊的Redis節點,所以也可以通過info命令來查詢它的相關信息
redis-cli -h 127.0.0.1 -p 26379 info sentinel
- 結果如下所示:
- Sentinel節點找到了主節點127.0.0.1:6379,發現了它的兩個從節點(slaves),同時發現Redis Sentinel一共有3個Sentinel節點(sentinels )
- 這裏只需要瞭解Sentinel節點能夠彼此感知到對方,同時能夠感知到Redis數據節點就可以了
- 當三個Sentinel節點都啓動後,整個拓撲結構如下圖所示:
- 至此Redis Sentinel已經搭建起來了,整體上還是比較容易的,但是有2點需要強調一下:
- 生產環境中建議Redis Sentinel的所有節點應該分佈在不同的物理機上
- Redis Sentinel中的數據節點和普通的Redis數據節點在配置上沒有任何區別,只不過是添加了一些Sentinel節點對它們進行監控
二、哨兵配置參數
默認配置文件
- Redis安裝目錄下有一個sentinel.conf,是默認的Sentinel節點配置文件,配置的參數如下所示:
port 26379 dir /opt/soft/redis/data 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 auth-pass <master-name> <password> #sentinel notification-script <master-name> <script-path> #sentinel client-reconfig-script <master-name> <script-path>
- port和dir分別代表Sentinel節點的端口和工作目錄,下面對其他參數進行介紹
sentinel monitor
- 格式如下:
sentinel monitor <master-name> <ip> <port> <quorum>
- 參數如下:
- 本配置說明此Sentinel節點要監控的是一個名字叫做<master-name>,ip地址和端口爲<ip> <port>的主節點
- <quorum>代表要判定主節點最終不可達所需要的票數。但實際上Sentinel節點會對所有節點進行監控,但是在Sentinel節點的配置中沒有看到有關從節點和其餘Sentinel節點的配置,那是因爲Sentinel節點會從主節點中獲取有關從節點以及其餘Sentinel節點的相關信息,有關這 部分是如何實現的,將在後面“sentinel實現原理”文章中介紹
- <quorum>參數用於故障發現和判定:例如將quorum配置爲2,代表至少有2個Sentinel節點認爲主節點不可達,那麼這個不可達的判定纔是客觀的。 對於<quorum>設置的越小,那麼達到下線的條件越寬鬆,反之越嚴格。一 般建議將其設置爲Sentinel節點的一半加1
- 同時<quorum>還與Sentinel節點的領導者選舉有關:至少要有 max(quorum,num(sentinels)/2+1)個Sentinel節點參與選舉,才能選出領導者Sentinel,從而完成故障轉移。例如有5個Sentinel節點,quorum=4,那麼 至少要有max(quorum,num(sentinels)/2+1)=4個在線Sentinel節點纔可以 進行領導者選舉
- 例如某個Sentinel初始節點配置如下:
port 26379 daemonize yes logfile "26379.log" dir /opt/soft/redis/data 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節點自動發現了從節點、其餘Sentinel節點
- 去掉了默認配置,例如parallel-syncs、failover-timeout參數
- 添加了配置紀元相關參數
- 啓動後變化爲:
port 26379 daemonize yes logfile "26379.log" dir "/opt/soft/redis/data" sentinel monitor mymaster 127.0.0.1 6379 2 sentinel config-epoch mymaster 0 sentinel leader-epoch mymaster 0 #發現兩個slave節點 sentinel known-slave mymaster 127.0.0.1 6380 sentinel known-slave mymaster 127.0.0.1 6381 #發現兩個sentinel節點 sentinel known-sentinel mymaster 127.0.0.1 26380 282a70ff56c36ed56e8f7ee6ada74124140d6f53 sentinel known-sentinel mymaster 127.0.0.1 26381 f714470d30a61a8e39ae031192f1feae7eb5b2be sentinel current-epoch 0
sentinel down-after-milliseconds
- 格式如下:
sentinel down-after-milliseconds <master-name> <times>
- 每個Sentinel節點都要通過定期發送ping命令來判斷Redis數據節點和其餘Sentinel節點是否可達,如果超過了down-after-milliseconds配置的時間且沒有有效的回覆,則判定節點不可達,<times>(單位爲毫秒)就是超時時間
- 這個配置是對節點失敗判定的重要依據
- 優化說明:down-after-milliseconds越大,代表Sentinel節點對於節點不可達的條件越寬鬆,反之越嚴格。條件寬鬆有可能帶來的問題是節點確實不可 達了,那麼應用方需要等待故障轉移的時間越長,也就意味着應用方故障時 間可能越長。條件嚴格雖然可以及時發現故障完成故障轉移,但是也存在一 定的誤判率
- 運維提示:down-after-milliseconds雖然以<master-name>爲參數,但實際上對Sentinel節點、主節點、從節點的失敗判定同時有效
sentinel parallel-syncs
- 格式如下:
sentinel parallel-syncs <master-name> <nums>
- 當Sentinel節點集合對主節點故障判定達成一致時,Sentinel領導者節點會做故障轉移操作,選出新的主節點,原來的從節點會向新的主節點發起復制操作
- parallel-syncs就是用來限制在一次故障轉移之後,每次向新的主節點發起復制操作的從節點個數。如果這個參數配置的比較大,那麼多個從節點會向新的主節點同時發起複製操作,儘管複製操作通常不會阻塞主節點, 但是同時向主節點發起復制,必然會對主節點所在的機器造成一定的網絡和磁盤IO開銷
- 下圖展示了一個案例,parallelsyncs=3會同時發起複製,parallel-syncs=1時從節點會輪詢發起複製
sentinel failover-timeout
- 格式如下:
sentinel failover-timeout <master-name> <times>
- failover-timeout通常被解釋成故障轉移超時時間,但實際上它作用於故障轉移的各個階段:
- a)選出合適從節點
- b)晉升選出的從節點爲主節點
- c)命令其餘從節點複製新的主節點
- d)等待原主節點恢復後命令它去複製新的主節點
- failover-timeout的作用具體體現在四個方面:
- 1)如果Redis Sentinel對一個主節點故障轉移失敗,那麼下次再對該主 節點做故障轉移的起始時間是failover-timeout的2倍
- 2)在b)階段時,如果Sentinel節點向a)階段選出來的從節點執行slaveof no one一直失敗(例如該從節點此時出現故障),當此過程超過 failover-timeout時,則故障轉移失敗
- 3)在b)階段如果執行成功,Sentinel節點還會執行info命令來確認a) 階段選出來的節點確實晉升爲主節點,如果此過程執行時間超過failovertimeout時,則故障轉移失敗
- 4)如果c)階段執行時間超過了failover-timeout(不包含複製時間), 則故障轉移失敗。注意即使超過了這個時間,Sentinel節點也會最終配置從 節點去同步最新的主節點
sentinel auth-pass
- 格式如下:
sentinel auth-pass <master-name> <password>
- 如果Sentinel監控的主節點配置了密碼,sentinel auth-pass配置通過添加主節點的密碼,防止Sentinel節點對主節點無法監控。
sentinel notification-script
- 配置如下:
sentinel notification-script <master-name> <script-path>
- 該配置的作用是在故障轉移期間,當一些警告級別的Sentinel事件發生(指重要事件,例如-sdown:客觀下線、-odown:主觀下 線)時,會觸發對應路徑的腳本,並向腳本發送相應的事件參數
- 例如在/opt/redis/scripts/下配置了notification.sh,該腳本會接收每個Sentinel節點傳過來的事件參數,可以利用這些參數作爲郵件或者短信報警依據:
#notification.sh #!/bin/sh #獲取所有參數 msg=$* #報警腳本或者接口,將msg作爲參數 exit 0
- 如果需要該功能,就可以在Sentinel節點添加如下配置:
sentinel notification-script mymaster /opt/redis/scripts/notification.sh
- 例如下面就是某個Sentinel節點對主節點做了主觀下線(有關主觀下線的概念在後面文章介紹)後腳本收到的參數:
+sdown master mymaster 127.0.0.1 6379
sentinel client-reconfig-script
- 配置如下:
sentinel client-reconfig-script <master-name> <script-path>
- 該選項的作用是在故障轉移結束後,會觸發對應路徑的腳本,並向腳本發送故障轉移結果的相關參數
- 例如在/opt/redis/scripts/下配置了client-reconfig.sh,該腳本會接收每個Sentinel節點傳過來的故障轉移結果參數,並觸發類似短信和郵件報警:
# client-reconfig.sh #!/bin/sh #獲取所有參數 msg=$* #報警腳本或者接口,將msg作爲參數 exit 0
- 如果需要該功能,就可以在Sentinel節點添加如下配置:
sentinel client-reconfig-script mymaster /opt/redis/scripts/client-reconfig.sh
- 當故障轉移結束,每個Sentinel節點會將故障轉移的結果發送給對應的腳本,具體參數如下:
- <master-name>:主節點名
- <role>:Sentinel節點的角色,分別是leader和observer,leader代表當前
- Sentinel節點是領導者,是它進行的故障轉移;observer是其餘Sentinel節點
- <from-ip>:原主節點的ip地址
- <from-port>:原主節點的端口
- <to-ip>:新主節點的ip地址
- <to-port>:新主節點的端口
<master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
- 例如以下內容分別是三個Sentinel節點發送給腳本的,其中一個是leader,另外兩個是observer:
mymaster leader start 127.0.0.1 6379 127.0.0.1 6380 mymaster observer start 127.0.0.1 6379 127.0.0.1 6380 mymaster observer start 127.0.0.1 6379 127.0.0.1 6380
- 有關sentinel notification-script和sentinel client-reconfig-script有幾點需要注意:
- <script-path>必須有可執行權限
- Redis規定腳本的最大執行時間不能超過60秒,超過後腳本將被殺掉
- 如果shell腳本以exit 1結束,那麼腳本稍後重試執行。如果以exit 2或者 更高的值結束,那麼腳本不會重試。正常返回值是exit 0
- 如果需要運維的Redis Sentinel比較多,建議不要使用這種腳本的形式 來進行通知,這樣會增加部署的成本。
- <script-path>開頭必須包含shell腳本頭(例如#!/bin/sh),否則事件發生時Redis將無法執行腳本產生如下錯誤:
-script-error /opt/sentinel/notification.sh 0 2
三、配置參數的調整
- 和普通的Redis數據節點一樣,Sentinel節點也支持動態地設置參數,而且和普通的Redis數據節點一樣並不是支持所有的參數
- 格式如下:
sentinel set <param> <value>
- 下圖是sentinel set命令支持的參數:
- 有幾點需要注意一下:
- 1)sentinel set命令只對當前Sentinel節點有效
- 2)sentinel set命令如果執行成功會立即刷新配置文件,這點和Redis普通數據節點設置配置需要執行config rewrite刷新到配置文件不同
- 3)建議所有Sentinel節點的配置儘可能一致,這樣在故障發現和轉移時比較容易達成一致
- 4)上圖中爲sentinel set支持的參數,具體可以參考源碼中的sentinel.c的 sentinelSetCommand函數
- 5)Sentinel對外不支持config命令
四、監控多個節點
- Redis Sentinel可以同時監控多個主節點,具體拓撲圖類似於下圖所示
- 配置方法也比較簡單,只需要指定多個masterName來區分不同的主節點即可。例如下面的配置監控monitor master-business-1和 monitor master-business-2兩個主節點:
# 監控1
sentinel monitor master-business-1 10.10.xx.1 6379 2
sentinel down-after-milliseconds master-business-1 60000
sentinel failover-timeout master-business-1 180000
sentinel parallel-syncs master-business-1 1
# 監控2
sentinel monitor master-business-2 10.16.xx.2 6380 2
sentinel down-after-milliseconds master-business-2 10000
sentinel failover-timeout master-business-2 180000
sentinel parallel-syncs master-business-2 1
五、部署技巧
①Sentinel節點不應該部署在一臺物理“機器”上
- 這裏特意強調物理機是因爲一臺物理機做成了若干虛擬機或者現今比較 流行的容器,它們雖然有不同的IP地址,但實際上它們都是同一臺物理機, 同一臺物理機意味着如果這臺機器有什麼硬件故障,所有的虛擬機都會受到影響
- 爲了實現Sentinel節點集合真正的高可用,請勿將Sentinel節點部署在 同一臺物理機器上
②部署至少3個且奇數個的Sentinel節點
- 3個以上是通過增加Sentinel節點的個數提高對於故障判定的準確性
- 因爲領導者選舉需要至少一半加1個節點,奇數個節點可以在滿足該條件的基礎上節省一個節點
- 有關Sentinel節點如何判斷節點失敗,如何選舉出一個Sentinel節點進行故障轉移將在後面“實現原理”文章介紹
③只有一套Sentinel,還是每個主節點配置一套Sentinel?
- Sentinel節點集合可以只監控一個主節點,也可以監控多個主節點,也就意味着部署拓撲可能有下面兩種情況
- 下面分別分析兩種方案的優缺點:
- 方案一:一套Sentinel,很明顯這種方案在一定程度上降低了維護成本,因爲只需要維護固定個數的Sentinel節點,集中對多個Redis數據節點進行管理就可以了。但是這同時也是它的缺點,如果這套Sentinel節點集合出現異常,可能會對多個Redis數據節點造成影響。還有如果監控的Redis數據節點較多,會造成Sentinel節點產生過多的網絡連接,也會有一定的影響
- 方案二:多套Sentinel,顯然這種方案的優點和缺點和上面是相反的, 每個Redis主節點都有自己的Sentinel節點集合,會造成資源浪費。但是優點 也很明顯,每套Redis Sentinel都是彼此隔離的
- 運維提示:如果Sentinel節點集合監控的是同一個業務的多個主節點集合,那麼使用方案一、否則一般建議採用方案二
五、哨兵API
- Sentinel節點是一個特殊的Redis節點,它有自己專屬的API
- 爲了方便演示,下面都以圖進行說明:
sentinel masters
- 展示所有被監控的主節點狀態以及相關的統計信息
- 例如:
sentinel master <master name>
- 展示指定<master name>的主節點狀態以及相關的統計信息
- 例如:
sentinel slaves <master name>
- 展示指定<master name>的從節點狀態以及相關的統計信息
- 例如:
sentinel sentinels <master name>
- 展示指定<master name>的Sentinel節點集合(不包含當前Sentinel節點)
- 例如:
sentinel get-master-addr-by-name <master name>
- 返回指定<master name>主節點的IP地址和端口
- 例如:
sentinel reset <pattern>
- 當前Sentinel節點對符合<pattern>(通配符風格)主節點的配置進行重置,包含清除主節點的相關狀態(例如故障轉移),重新發現從節點和Sentinel節點
- 例如sentinel-1節點對mymaster-1節點重置狀態如下:
sentinel failover <master name>
- 對指定<master name>主節點進行強制故障轉移(沒有和其他Sentinel節點“協商”),當故障轉移完成後,其他Sentinel節點按照故障轉移的結果更新自身配置
- 這個命令在Redis Sentinel的日常運維中非常有用,將在後面“開發與運維中的問題”一文中進行介紹:https://blog.csdn.net/qq_41453285/article/details/106419183
- 例如,對mymaster-2進行故障轉移:
- 執行命令前,mymaster-2是127.0.0.1:6382
- 執行命令後:mymaster-2由原來的一個從節點127.0.0.1:6383代替
sentinel ckquorum <master name>
- 檢測當前可達的Sentinel節點總數是否達到<quorum>的個數
- 見上面的sentinel monitor配置參數
- 例如quorum=3,而當前可達的Sentinel節點個數爲2個,那麼將無法進行故障轉移,Redis Sentinel的高可用特性也將失去
- 例如:
sentinel flushconfig
- 將Sentinel節點的配置強制刷到磁盤上,這個命令Sentinel節點自身用得比較多,對於開發和運維人員只有當外部原因(例如磁盤損壞)造成配置文件損壞或者丟失時,這個命令是很有用的
- 例如:
sentinel remove <master name>
- 取消當前Sentinel節點對於指定<master name>主節點的監控
- 例如sentinel-1當前對mymaster-1進行了監控:
- 例如下面,sentinel-1節點取消對mymaster-1節點的監控,但是要注意這個命令僅僅對當前Sentinel節點有效
- 再執行info sentinel命令,發現sentinel-1已經失去對mymaster-1的監控:
sentinel monitor <master name> <ip> <port> <quorum>
- 這個命令和配置文件中的含義是完全一樣的,只不過是通過命令的形式來完成Sentinel節點對主節點的監控
- 例如命令sentinel-1節點重新監控mymaster-1節點:
- 命令執行後,發現sentinel-1節點重新對mymaster-1節點進行監控:
sentinel set <master name>
- 動態修改Sentinel節點配置選項,這個命令已經在上面介紹了,這裏就不贅述了
sentinel is-master-down-by-addr
- Sentinel節點之間用來交換對主節點是否下線的判斷,根據參數的不同,還可以作爲Sentinel領導者選舉的通信方式
- 在後面“實現原理”一文中會詳細介紹