天天看點

Redis Sentinel(哨兵)搭建步驟(四)

上一篇講述隆redis主從複制步驟(https://blog.csdn.net/u014399489/article/details/94392891) ,沒有太難配置,隻需要簡單在slave伺服器redis.conf添加slaveof 參數,就可以實作主從配置,假如master當機了,Redis本身(包括它的很多用戶端)都沒有實作自動進行主從切換,Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案

主從的缺點

a)主從複制,若主節點出現問題,則不能提供服務,需要人工修改配置将從變主
b)主從複制主節點的寫能力單機,能力有限
c)單機節點的存儲能力也有限
           

主從故障如何故障轉移

a)主節點(master)故障,從節點slave-1端執行 slaveof no one後變成新主節點;
b)其它的節點成為新主節點的從節點,并從新節點複制資料;
c)需要人工幹預,無法實作高可用。
           

redis從2.8開始正式提供了Redis Sentinel(哨兵)架構來解決這個問題,Redis Sentinel是一個分布式架構,其中包含若幹個Sentinel節點和Redis資料節點,每個Sentinel節點會對資料節點和其餘Sentinel節點進行監控,當它發現節點不可達時,會對節點做下線辨別。如果被辨別的是主節點,它還會和其他Sentinel節點進行“協商”,當大多數Sentinel節點都認為主節點不可達時,它們會選舉出一個Sentinel節點來完成自動故障轉移的工作,同時會将這個變化通知給Redis應用方。整個過程完全是自動的,不需要人工來介入,是以這套方案很有效地解決了Redis的高可用問題。

實作原理:

三個定時監控任務
           
1)每隔10秒,每個Sentinel節點會向主節點和從節點發送info指令擷取最新的拓撲結構。
2)每隔2秒,每個Sentinel節點會向Redis資料節點的__sentinel__:hello頻道上發送該Sentinel節點對于主節點的判斷以及  ,
目前Sentinel節點的資訊,同時每個Sentinel節點也會訂閱該頻道,來了解其他Sentinel節點以及它們對主節點的判斷。
3)每隔一秒,每個Sentinel節點會向主節點、從節點、其餘Sentinel節點發送一條ping指令做一次心跳檢測,來确認這些節
點目前是否可達。
           
主觀下線
           

因為每隔一秒,每個Sentinel節點會向主節點、從節點、其餘Sentinel節點發送一條ping指令做一次心跳檢測,當這些節點超過down-after-milliseconds沒有進行有效回複,Sentinel節點就會對該節點做失敗判定,這個行為叫做主觀下線。

客觀下線
           

當Sentinel主觀下線的節點是主節點時,該Sentinel節點會向其他Sentinel節點詢問對主節點的判斷,當超過個數,那麼意味着大部分的Sentinel節點都對這個主節點的下線做了同意的判定,于是該Sentinel節點認為主節點确實有問題,這時該Sentinel節點會做出客觀下線的決定。

上司者Sentinel節點選舉
           

Raft算法:假設s1(sentinel-1)最先完成客觀下線,它會向其餘Sentinel節點發送指令,請求成為上司者;收到指令的Sentinel節點如果沒有同意過其他Sentinel節點的請求,那麼就會同意s1的請求,否則拒絕;如果s1發現自己的票數已經大于等于某個值,那麼它将成為上司者。

故障轉移
           

1)上司者Sentinel節點在從節點清單中選出一個節點作為新的主節點

2)上一步的選取規則是與主節點複制相似度最高的從節點

3)上司者Sentinel節點讓剩餘的從節點成為新的主節點的從節點

4)Sentinel節點集合會将原來的主節點更新為從節點,并保持着對其關注,當其恢複後指令它去複制新的主節點

實驗環境

redis哨兵模式需要在上一篇redis主從複制到環境下搭建,這裡就不在叙述redis主從複制搭建環境,可以參考https://blog.csdn.net/u014399489/article/details/94392891 文章,需要注意到一點,主從複制一篇文章中設定

通路密碼 requirepass,redis哨兵模式下,master當機時候從新啟動就會變成slave,此時到slave通路同步master

就需要通路密碼需要在主從複制到master配置檔案中同時設定requirepass 和 masterauth ,這樣在主從切換到時候

才能正常到同步資料。

1)搭建:(環境:redis服務3個執行個體 6378、6377、6376;sentinel服務3個監控:26378、26377、26376)
           

sentinel是一個"螢幕",根據被監視執行個體的身份和狀态來判斷該執行何種操作。通過給定的配置檔案來發現主伺服器的,再通過向主伺服器發送的info資訊來發現該主伺服器的從伺服器。Sentinel 實際上就是一個運作在 Sentienl 模式下的 Redis 伺服器,是以我們同樣可以使用以下指令來啟動一個 Sentinel執行個體。運作方式如下:

# 拷貝redis目錄下到sentinel.conf檔案到相應到redis-sentinel目錄下

[[email protected] local]# cp redis/sentinel.conf  redis-master/sentinel.conf 
[[email protected] local]# cp redis/sentinel.conf  redis-slave1/sentinel.conf 
[[email protected] local]# cp redis/sentinel.conf  redis-slave2/sentinel.conf 

# 啟動sentinel 哨兵

[[email protected] local]# ./redis/src/redis-sentinel  redis-master/sentinel.conf 
           

master目錄下到sentinel.conf 配置資訊如下

port 20086      #預設端口26379

dir "/tmp"

logfile "/var/log/redis/sentinel_20086.log"   #sentinel啟動後日志檔案

daemonize yes   # 啟動sentinel是否是背景應用程式,預設是no,修改成yes背景啟動

#格式:sentinel <option_name> <master_name> <option_value>;#該行的意思是:監控的master的名字叫做mymaster(自定義),位址為127.0.0.1:6378 ,行尾最後的一個1代表在sentinel叢集中,多少個sentinel認為masters死了,才能真正認為該master不可用了,該值需要小于目前到sentinel個數(基數個),不然啟動sentinel一直提示  +sentinel-address-switch 資訊。
sentinel monitor mymaster  127.0.0.1 6378 1  

#sentinel會向master發送心跳PING來确認master是否存活,如果master在“一定時間範圍”内不回應PONG 或者是回複了一個錯誤消息,那麼這個sentinel會主觀地(單方面地)認為這個master已經不可用了(subjectively down, 也簡稱為SDOWN)。而這個down-after-milliseconds就是用來指定這個“一定時間範圍”的,機關是毫秒,預設30秒。
sentinel down-after-milliseconds mymaster  15000

#failover過期時間,當failover開始後,在此時間内仍然沒有觸發任何failover操作,目前sentinel将會認為此次failoer失敗。預設180秒,即3分鐘。
sentinel failover-timeout mymaster   120000

#在發生failover主備切換時,這個選項指定了最多可以有多少個slave同時對新的master進行同步,這個數字越小,完成failover所需的時間就越長,但是如果這個數字越大,就意味着越多的slave因為replication而不可用。可以通過将這個值設為 1 來保證每次隻有一個slave處于不能處理指令請求的狀态。
sentinel parallel-syncs mymaster   1

#sentinel 連接配接設定了密碼的主和從
#sentinel auth-pass <master_name> xxxxx

#發生切換之後執行的一個自定義腳本:如發郵件、vip切換等
##sentinel notification-script <master-name> <script-path>     ##不會執行,疑問?
#sentinel client-reconfig-script <master-name> <script-path>  ##這個會執行
           

注意:要是參數配置的是預設值,在sentinel運作時該參數會在配置檔案檔案裡被删除掉,直接不顯示。也可以在運作時用指令SENTINEL SET command動态修改,後面說明。

很顯然,隻使用單個sentinel程序來監控redis叢集是不可靠的,當sentinel程序宕掉後(sentinel本身也有單點問題,single-point-of-failure)整個叢集系統将無法按照預期的方式運作。是以有必要将sentinel叢集,這樣有幾個好處:

1:即使有一些sentinel程序宕掉了,依然可以進行redis叢集的主備切換;
2:如果隻有一個sentinel程序,如果這個程序運作出錯,或者是網絡堵塞,那麼将無法實作redis叢集的主備切換(單點問題);
3:如果有多個sentinel,redis的用戶端可以随意地連接配接任意一個sentinel來獲得關于redis叢集中的資訊。
           

本文開啟sentinel叢集用了3個執行個體,保證各個端口和目錄不一緻,配置檔案如下:

redis-master/sentinel.conf :

port   26378

dir "/var/lib/sentinel_26378"

logfile "/usr/local/redis-master/sentinel_26378.log"

daemonize yes

sentinel monitor mymaster 192.168.2.166 6378  1
sentinel auth-pass 123456
sentinel down-after-milliseconds mymaster  15000

sentinel failover-timeout mymaster  120000

sentinel parallel-syncs mymaster  1

#發生切換之後執行的一個自定義腳本:如發郵件、vip切換等
#sentinel notification-script <master-name> <script-path>
           

redis-slave1/sentinel.conf :

port   26377

dir "/var/lib/sentinel_26377"

logfile "/usr/local/redis-master/sentinel_26377.log"

daemonize yes

sentinel monitor mymaster 192.168.2.166 6378  1
sentinel auth-pass 123456
sentinel down-after-milliseconds mymaster  15000

sentinel failover-timeout mymaster  120000

sentinel parallel-syncs mymaster  1

#發生切換之後執行的一個自定義腳本:如發郵件、vip切換等
#sentinel notification-script <master-name> <script-path>
           

redis-slave1/sentinel.conf :

port   26376

dir "/var/lib/sentinel_26376"

logfile "/usr/local/redis-master/sentinel_26376.log"

daemonize yes

sentinel monitor mymaster 192.168.2.166 6378  1
sentinel auth-pass 123456
sentinel down-after-milliseconds mymaster  15000

sentinel failover-timeout mymaster  120000

sentinel parallel-syncs mymaster  1

#發生切換之後執行的一個自定義腳本:如發郵件、vip切換等
#sentinel notification-script <master-name> <script-path>
           

啟動sentinel:

[[email protected] local]# ./redis/src/redis-sentinel  redis-master/sentinel.conf 
 [[email protected] local]# ./redis/src/redis-sentinel  redis-slave1/sentinel.conf 
 [[email protected] local]# ./redis/src/redis-sentinel  redis-slave2/sentinel.conf 
           

注意:當一個master配置為需要密碼才能連接配接時,用戶端和slave在連接配接時都需要提供密碼。master通過requirepass設定自身的密碼,不提供密碼無法連接配接到這個master。slave通過masterauth來設定通路master時的密碼。用戶端需要auth提供密碼,但是當使用了sentinel時,由于一個master可能會變成一個slave,一個slave也可能會變成master,是以需要同時設定上述兩個配置項,并且sentinel需要連接配接master和slave,需要設定參數:sentinel auth-pass <master_name> xxxxx。

23824:X 03 Jul 12:58:25.444 # Sentinel ID is 0fd362aead9d534978032c8c6bb7703e980a3b32
23824:X 03 Jul 12:58:25.444 # +monitor master mymaster 192.168.2.166 6378 quorum 1  #主加入監控
23824:X 03 Jul 12:58:25.445 * +slave slave 192.168.2.166:6377 192.168.2.166 6377 @ mymaster 192.168.2.166 6378  #檢測到一個slave并添加進slave清單
23824:X 03 Jul 12:58:25.449 * +slave slave 192.168.2.166:6376 192.168.2.166 6376 @ mymaster 192.168.2.166 6378 #檢測到一個slave并添加進slave清單  
 23824:X 03 Jul 12:58:25.459 +sentinel sentinel 192.168.2.166:6377 192.168.2.166  6377 @ mymaster  192.168.2.166 6378   #增加了一個sentinel
 23824:X 03 Jul 12:58:25.469 +sentinel sentinel 192.168.2.166:6376 192.168.2.166  6376 @ mymaster  192.168.2.166 6378  #增加了一個sentinel
 
           

故障轉移

我們關閉master主節點,當然我示範的項目中master伺服器是166,因為我之前有測試過,是以大家在操作的時候可以按照自己機器上的為主。

第一步:我們關閉166的redis,等待一會,我們再檢視一下sentinel的日志。我們通過日志來分析一下自動故障轉移的流程

=======================134master發現不能用
40325:X 09 Jan 2019 16:46:09.920 # +sdown master mymaster 192.168.250.134 7002

=======================投票後有兩個sentinel發現master不能用
40325:X 09 Jan 2019 16:46:10.005 # +odown master mymaster 192.168.250.134 7002 #quorum 2/2

=======================目前配置版本被更新
40325:X 09 Jan 2019 16:46:10.005 # +new-epoch 2

=======================達到故障轉移failover條件,正等待其他sentinel的選舉
40325:X 09 Jan 2019 16:46:10.005 # +try-failover master mymaster 192.168.250.134 7002

=======================進行投票選舉slave伺服器
40325:X 09 Jan 2019 16:46:10.006 # +vote-for-leader 7985977d2db7df47bce251c06d50f77c3917d184 2
40325:X 09 Jan 2019 16:46:10.007 # f53245a5100693311aeaf090b903de8587b3743a voted for 7985977d2db7df47bce251c06d50f77c3917d184 2
40325:X 09 Jan 2019 16:46:10.008 # c8e067032a78eafcdca9636cb4d9777b492daea6 voted for 7985977d2db7df47bce251c06d50f77c3917d184 2
40325:X 09 Jan 2019 16:46:10.077 # +elected-leader master mymaster 192.168.250.134 7002
40325:X 09 Jan 2019 16:46:10.077 # +failover-state-select-slave master mymaster 192.168.250.134 7002

=======================選擇一個slave當選新的master
40325:X 09 Jan 2019 16:46:10.178 # +selected-slave slave 192.168.250.132:7000 192.168.250.132 7000 @ mymaster 192.168.250.134 7002

=======================把選舉出來的slave進行身份master切換
40325:X 09 Jan 2019 16:46:10.178 * +failover-state-send-slaveof-noone slave 192.168.250.132:7000 192.168.250.132 7000 @ mymaster 192.168.250.134 7002
40325:X 09 Jan 2019 16:46:10.241 * +failover-state-wait-promotion slave 192.168.250.132:7000 192.168.250.132 7000 @ mymaster 192.168.250.134 7002
40325:X 09 Jan 2019 16:46:10.393 # +promoted-slave slave 192.168.250.132:7000 192.168.250.132 7000 @ mymaster 192.168.250.134 7002

=======================把故障轉移failover改變reconf-slaves
40325:X 09 Jan 2019 16:46:10.393 # +failover-state-reconf-slaves master mymaster 192.168.250.134 7002

=======================sentinel發送slaveof指令把133重新同步132master
40325:X 09 Jan 2019 16:46:10.448 * +slave-reconf-sent slave 192.168.250.133:7001 192.168.250.133 7001 @ mymaster 192.168.250.134 7002

=======================重寫rewrite master位址到sentinel配置檔案中 
40325:X 09 Jan 2019 16:46:10.738 * +sentinel-address-switch master mymaster 192.168.250.134 7002 ip 192.168.250.132 port 26379 for c8e067032a78eafcdca9636cb4d9777b492daea6
40325:X 09 Jan 2019 16:46:10.907 * +sentinel-address-switch master mymaster 192.168.250.134 7002 ip 192.168.250.138 port 26379 for c8e067032a78eafcdca9636cb4d9777b492daea6

=======================離開不可用的master
40325:X 09 Jan 2019 16:46:11.135 # -odown master mymaster 192.168.250.134 7002

=======================slave被重新配置為另外一個master的slave,但資料還未發生
40325:X 09 Jan 2019 16:46:11.407 * +slave-reconf-inprog slave 192.168.250.133:7001 192.168.250.133 7001 @ mymaster 192.168.250.134 7002

=======================與master進行資料同步
40325:X 09 Jan 2019 16:46:11.407 * +slave-reconf-done slave 192.168.250.133:7001 192.168.250.133 7001 @ mymaster 192.168.250.134 7002

=======================故障轉移完成
40325:X 09 Jan 2019 16:46:11.508 # +failover-end master mymaster 192.168.250.134 7002

=======================master位址發生改變
40325:X 09 Jan 2019 16:46:11.508 # +switch-master mymaster 192.168.250.134 7002 192.168.250.132 7000

=======================檢測slave并添加到slave清單
40325:X 09 Jan 2019 16:46:11.508 * +slave slave 192.168.250.133:7001 192.168.250.133 7001 @ mymaster 192.168.250.132 7000
40325:X 09 Jan 2019 16:46:11.508 * +slave slave 192.168.250.134:7002 192.168.250.134 7002 @ mymaster 192.168.250.132 7000
40325:X 09 Jan 2019 16:46:12.475 * +sentinel-address-switch master mymaster 192.168.250.132 7000 ip 192.168.250.132 port 26379 for c8e067032a78eafcdca9636cb4d9777b492daea
           

繼續閱讀