一、引言
上一篇文章我們詳細的講解了Redis的主從叢集模式,其實這個叢集模式配置很簡單,隻需要在Slave的節點上進行配置,Master主節點的配置不需要做任何更改,但是有一點,Master和Slave兩個節點的持久化配置盡量保持一緻,否則會有奇怪的問題出現。從今天開始我們開始講Redis叢集模式的第二模式,也就是“哨兵”模式,該模式是從Redis的2.6版本開始提供的,但是當時這個版本的模式是不穩定的,直到Redis的2.8版本以後,這個哨兵模式才穩定下來,在生産環境中,如果想要使用Redis的哨兵模式,也會盡量使用Redis的2.8版本之後的版本。無論是主從模式,還是哨兵模式,這兩個模式都有一個問題,不能水準擴容,并且這兩個模式的高可用特性都會受到Master主節點記憶體的限制。還有一點,實作哨兵模式的配置也不簡單,甚至可以說有些繁瑣,是以在工業場景裡這兩個模式都不建議使用,如果要使用必須有相關的問題的解決方案,以免後續帶來的問題。
二、Redis Sentinel簡介
Sentinel(哨兵)程序是用于監控redis叢集中Master主伺服器工作的狀态,在Master主伺服器發生故障的時候,可以實作Master和Slave伺服器的切換,保證系統的高可用,其已經被內建在redis2.6+的版本中,Redis的哨兵模式到了2.8版本之後就穩定了下來。一般在生産環境也建議使用Redis的2.8版本的以後版本。哨兵(Sentinel) 是一個分布式系統,你可以在一個架構中運作多個哨兵(sentinel) 程序,這些程序使用流言協定(gossipprotocols)來接收關于Master主伺服器是否下線的資訊,并使用投票協定(Agreement Protocols)來決定是否執行自動故障遷移,以及選擇哪個Slave作為新的Master。每個哨兵(Sentinel)程序會向其它哨兵(Sentinel)、Master、Slave定時發送消息,以确認對方是否”活”着,如果發現對方在指定配置時間(可配置的)内未得到回應,則暫時認為對方已掉線,也就是所謂的”主觀認為當機” ,英文名稱:Subjective Down,簡稱SDOWN。有主觀當機,肯定就有客觀當機。當“哨兵群”中的多數Sentinel程序在對Master主伺服器做出 SDOWN 的判斷,并且通過 SENTINEL is-master-down-by-addr 指令互相交流之後,得出的Master Server下線判斷,這種方式就是“客觀當機”,英文名稱是:Objectively Down, 簡稱 ODOWN。通過一定的vote算法,從剩下的slave從伺服器節點中,選一台提升為Master伺服器節點,然後自動修改相關配置,并開啟故障轉移(failover)。
哨兵(sentinel) 雖然有一個單獨的可執行檔案 redis-sentinel ,但實際上它隻是一個運作在特殊模式下的 Redis 伺服器,你可以在啟動一個普通 Redis 伺服器時通過給定 --sentinel 選項來啟動哨兵(sentinel),哨兵(sentinel) 的一些設計思路和zookeeper非常類似。
Sentinel叢集之間會互相通信,溝通交流redis節點的狀态,做出相應的判斷并進行處理,這裡的主觀下線狀态和客觀下線狀态是比較重要的狀态,它們決定了是否進行故障轉移,可以 通過訂閱指定的頻道資訊,當伺服器出現故障得時候通知管理者,用戶端可以将 Sentinel 看作是一個隻提供了訂閱功能的 Redis 伺服器,你不可以使用 PUBLISH 指令向這個伺服器發送資訊,但你可以用 SUBSCRIBE 指令或者 PSUBSCRIBE 指令, 通過訂閱給定的頻道來擷取相應的事件提醒。一個頻道能夠接收和這個頻道的名字相同的事件。 比如說, 名為 +sdown 的頻道就可以接收所有執行個體進入主觀下線(SDOWN)狀态的事件。
1、Sentinel(哨兵)程序的作用:
1】、監控(Monitoring): 哨兵(sentinel) 會不斷地檢查你的Master和Slave是否運作正常。
2】、提醒(Notification):當被監控的某個Redis節點出現問題時, 哨兵(sentinel) 可以通過 API 向管理者或者其他應用程式發送通知。
3】、自動故障遷移(Automatic failover):當一個Master不能正常工作時,哨兵(sentinel) 會開始一次自動故障遷移操作,它會将失效Master的其中一個Slave更新為新的Master, 并讓失效Master的其他Slave改為複制新的Master;當用戶端試圖連接配接失效的Master時,叢集也會向用戶端傳回新Master的位址,使得叢集可以使用現在的Master替換失效Master。Master和Slave伺服器切換後,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置檔案的内容都會發生相應的改變,即,Master主伺服器的redis.conf配置檔案中會多一行slaveof的配置,sentinel.conf的監控目标會随之調換。
2、Sentinel(哨兵)程序的工作方式:
1】、每個Sentinel(哨兵)程序以每秒鐘一次的頻率向整個叢集中的Master主伺服器,Slave從伺服器以及其他Sentinel(哨兵)程序發送一個 PING 指令。
2】、如果一個執行個體(instance)距離最後一次有效回複 PING 指令的時間超過 down-after-milliseconds 選項所指定的值, 則這個執行個體會被 Sentinel(哨兵)程序标記為主觀下線(SDOWN)。
3】、如果一個Master主伺服器被标記為主觀下線(SDOWN),則正在監視這個Master主伺服器的所有 Sentinel(哨兵)程序要以每秒一次的頻率确認Master主伺服器的确進入了主觀下線狀态。
4】、當有足夠數量的 Sentinel(哨兵)程序(大于等于配置檔案指定的值)在指定的時間範圍内确認Master主伺服器進入了主觀下線狀态(SDOWN), 則Master主伺服器會被标記為客觀下線(ODOWN)。
5】、在一般情況下, 每個 Sentinel(哨兵)程序會以每 10 秒一次的頻率向叢集中的所有Master主伺服器、Slave從伺服器發送 INFO 指令。
6】、當Master主伺服器被 Sentinel(哨兵)程序标記為客觀下線(ODOWN)時,Sentinel(哨兵)程序向下線的 Master主伺服器的所有 Slave從伺服器發送 INFO 指令的頻率會從 10 秒一次改為每秒一次。
7】、若沒有足夠數量的 Sentinel(哨兵)程序同意 Master主伺服器下線, Master主伺服器的客觀下線狀态就會被移除。若 Master主伺服器重新向 Sentinel(哨兵)程序發送 PING 指令傳回有效回複,Master主伺服器的主觀下線狀态就會被移除。
3、哨兵模式的環境:
1】、Master主伺服器配置資訊:IP:192.168.127.128, Port:6379,OS:Linux
2】、Slave從伺服器的配置資訊:IP:192.168.127.129 Port:6379,OS:Linux
3】、在Slave從伺服器上安裝了一個哨兵程序(Sentinel),在Master伺服器也安裝了一個哨兵程序(Sentinel)。
由于兩個Redis伺服器都是安裝在Linux作業系統上,而且這兩個Redis伺服器會在Master主伺服器發生故障的時候會進行切換,必須保證兩個Redis伺服器的端口号已經增加進了防火牆,或者把兩個Linux作業系統的防火牆關閉,否則會提示Master-link-Status:down,沒有連接配接上Master主伺服器。解決辦法有兩個:第一個辦法是關閉兩個Linux作業系統的防火牆;第二個辦法是把各個Redis服務的端口号增加到防火牆裡面,允許通過該端口号進行通信。可以先使用指令 【firewall-cmd --query-port=6379/tcp】,如果結果是 No,那就繼續執行以下指令【firewall-cmd --add-port=6379/tcp】,指令執行後,傳回Success,表示增加成功。這樣兩個Linux系統上的Redis伺服器就可以順利切換,執行哨兵模式的操作。
三、哨兵模式的配置
下面是我使用的配置,需要修改的配置項我寫了出來,沒有更改的配置項就是用預設值,就不會寫出來:
1、###### Master config(redis.conf)
2、###### Slave Config(redis.conf)
3、###### Sentinel Config(sentinel.conf,192.168.127.129 Slave從伺服器)
4、###### 模式測試
4.1、在Sentinel.conf配置檔案設定 sentinel monitor:
4.2、在Sentinel.conf配置檔案設定 sentinel down-after-milliseconds:
4.3、在Sentinel.conf配置檔案設定 sentinel parallel-syncs:
4.4、Master 主伺服器的配置詳情:
4.5、Slave 從伺服器配置詳情:
4.6、啟動Sentinel(哨兵)程序,開始對Master主伺服器進行監控:
4.7、我們人為模仿Master主伺服器當機:
4.8、實作Master主伺服器和Slave從伺服器的切換:
4.9、主從切換後,主伺服器變成了Slave 從伺服器,詳情如下:
4.10、主從切換後,從伺服器變成了Master 主伺服器,詳情如下:
注意:
① INFO
sentinel的基本狀态資訊
②SENTINEL masters
列出所有被監視的主伺服器,以及這些主伺服器的目前狀态
③ SENTINEL slaves
列出給定主伺服器的所有從伺服器,以及這些從伺服器的目前狀态
④SENTINEL get-master-addr-by-name
傳回給定名字的主伺服器的 IP 位址和端口号
⑤SENTINEL reset
重置所有名字和給定模式 pattern 相比對的主伺服器。重置操作清除主伺服器目前的所有狀态, 包括正在執行中的故障轉移, 并移除目前已經發現和關聯的, 主伺服器的所有從伺服器和 Sentinel 。
⑥SENTINEL failover
當主伺服器失效時, 在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移,但是它會給其他sentinel發送一個最新的配置,其他sentinel會根據這個配置進行更新
四、主觀下線和客觀下線
下面我們來解釋一下兩個“下線”的概念,一個是“主觀下線”,另一個就是“客觀下線”。
主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個 Sentinel 執行個體對伺服器做出的下線判斷。
客觀下線(Objectively Down, 簡稱 ODOWN)指的是多個 Sentinel 執行個體在對同一個伺服器做出 SDOWN 判斷,并且通過 SENTINEL is-master-down-by-addr 指令互相交流之後,得出的伺服器下線判斷。(一個 Sentinel 可以通過向另一個 Sentinel 發送 SENTINEL is-master-down-by-addr 指令來詢問對方是否認為給定的伺服器已下線。)
如果一個伺服器沒有在 master-down-after-milliseconds 選項所指定的時間内,對向它發送 PING 指令的 Sentinel(哨兵)程序傳回一個有效回複(valid reply),那麼 Sentinel(哨兵)程序就會将這個伺服器标記為主觀下線。
伺服器對 PING 指令的有效回複可以是以下三種回複的其中一種:
1、傳回 +PONG 。
2、傳回 -LOADING 錯誤。
3、傳回 -MASTERDOWN 錯誤。
如果伺服器傳回除以上三種回複之外的其他回複,又或者在指定時間内沒有回複 PING 指令,那麼 Sentinel(哨兵)程序認為伺服器傳回的回複無效(non-valid)。
如果一個伺服器在 master-down-after-milliseconds 毫秒内,一直傳回無效回複才會被 Sentinel 标記為主觀下線。
舉個例子,如果 master-down-after-milliseconds 選項的值為 30000 毫秒(30 秒),那麼隻要伺服器能在每 29 秒之内傳回至少一次有效回複, 這個伺服器就仍然會被認為是處于正常狀态的。
從“主觀下線”狀态切換到“客觀下線”狀态并沒有使用嚴格的法定人數算法(strong quorum algorithm),而是使用了流言協定,該協定解釋為:如果 Sentinel(哨兵)程序在給定的時間範圍内,從其他 Sentinel(哨兵)程序那裡接收到了足夠數量的主伺服器下線報告, 那麼 Sentinel(哨兵)程序就會将主伺服器的狀态從“主觀下線”改變為“客觀下線”。如果之後其他 Sentinel(哨兵)程序不再報告主伺服器已下線,那麼“客觀下線”狀态就會被移除。
“客觀下線”條件隻适用于主伺服器:對于任何其他類型的 Redis 執行個體, Sentinel(哨兵)程序在将它們判斷為下線前不需要進行協商,是以Slave從伺服器或者其他 Sentinel(哨兵)程序永遠不會達到“客觀下線”條件。
隻要有一個 Sentinel(哨兵)程序發現某個主伺服器進入了“客觀下線”狀态,這個 Sentinel(哨兵)程序就可能會被其他 Sentinel(哨兵)程序推選出,并對失效的主伺服器執行自動故障遷移操作。
五、Sentinel(哨兵)配置檔案簡介
在Redis的源碼中包含了一個名為 sentinel.conf 的檔案, 這個檔案就是帶有注釋的Sentinel(哨兵)的配置檔案的示例。
如果想要運作一個“哨兵”程式,以下配置項是最少配置:
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
第一行配置表示 Sentinel(哨兵)程序去監視一個名為 mymaster 的主伺服器,這個主伺服器的 IP 位址為 127.0.0.1 , 端口号為 6379,而将這個主伺服器判斷為失效至少需要 1 個 Sentinel(哨兵)程序的同意。如果在架構系統中已經配置類多個Sentinel(哨兵)程序,在同意“Master主伺服器”下線的 Sentinel(哨兵)程序的數量不達标的情況下,Sentinel(哨兵)程序就不會執行自動故障遷移。在設定多Sentinel(哨兵)程序的情況下,無論設定多少個 Sentinel(哨兵)程序同意才能判斷一個伺服器失效,一個 Sentinel 都需要獲得架構系統中多數 Sentinel(哨兵)程序的支援, 才能發起一次自動故障遷移,并預留一個給定的配置紀元 (configuration Epoch ,一個配置紀元就是一個新主伺服器配置的版本号)。如果您隻配置了一個Sentinel(哨兵)程序來做監控,那一個Sentinel(哨兵)程序也可以決定“Master主伺服器”是否下線。
其他選項的基本格式如下:sentinel <選項的名字> <主伺服器的名字> <選項的值>
配置選項的解釋如下:
1、down-after-milliseconds : Sentinel(哨兵)程序判斷伺服器已經掉線所需的毫秒數。
如果被監控的伺服器在給定的毫秒數之内,并沒有傳回 Sentinel(哨兵)程序發送的 PING 指令的回複,或者傳回一個錯誤,那麼 Sentinel(哨兵)程序将這個伺服器标記為主觀下線(subjectively down,簡稱 SDOWN )。如果在架構系統中配置了多個Sentinel(哨兵)程序的情況下,隻有一個Sentinel(哨兵)程序将伺服器标記為主觀下線并不一定會引起伺服器的自動故障遷移,隻有在足夠數量的 Sentinel(哨兵)程序都将一個伺服器标記為主觀下線之後,伺服器才會被标記為客觀下線(objectively down, 簡稱 ODOWN ),這時才回執行自動故障遷移。另外一種情況是,在架構系統中隻配置了一個Sentinel(哨兵)程序的話,那這Sentinel(哨兵)程序也可以決定被監控的伺服器的是否“下線”。
将伺服器标記為客觀下線所需的 Sentinel(哨兵)程序數量由對主伺服器的配置決定。
2、parallel-syncs :在執行故障轉移時,最多可以有多少個從伺服器同時對新的主伺服器進行同步,這個數字越小,完成故障轉移所需的時間就越長。
如果“Slave從伺服器”被設定為允許使用過期資料集(參見對 redis.conf 檔案中對 slave-serve-stale-data 選項的說明),那麼你可能不希望所有“Slave從伺服器”都在同一時間向新的“Master主伺服器”發送同步請求, 因為盡管複制過程的絕大部分步驟都不會阻塞“Slave從伺服器”,但“Slave從伺服器”在載入“Master主伺服器”發來的 RDB 檔案時, 仍然會造成“Slave從伺服器”在一段時間内不能處理指令請求,如果全部“Slave從伺服器”一起對新的“Master主伺服器”進行同步, 那麼就可能會造成所有“Slave從伺服器”在短時間内全部不可用的情況出現。
你可以通過将這個值設為 1 來保證每次隻有一個Slave從伺服器處于不能處理指令請求的狀态。
3、failover-timeout:實作主從切換,完成故障轉移的所需要的最大時間值。若Sentinel(哨兵)程序在該配置值内未能完成故障轉移的操作(即故障時master/slave自動切換),則認為本次故障轉移操作失敗。
4、notification-script: 指定Sentinel(哨兵)程序檢測到Master-Name所指定的“Master主伺服器”的執行個體異常的時候,所要調用的報警腳本。該配置項可選,但線上系統建議配置。
六、哨兵模式的優缺點
優點:
1、哨兵叢集模式是基于主從模式的,所有主從的優點,哨兵模式同樣具有。
2、主從可以切換,故障可以轉移,系統可用性更好。
3、哨兵模式是主從模式的更新,系統更健壯,可用性更高。
缺點:
1、Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。為避免這一問題,運維人員在系統上線時必須確定有足夠的空間,這對資源造成了很大的浪費。
七、結束
今天就寫到這裡了,Redis的哨兵模式是以主從模式為基礎的,是以說,主從模式擁有的一些缺點,在哨兵模式下也具有。哨兵模式主要是監控Master主伺服器的運作情況,當然也會監控Slave從伺服器的運作情況,如果Master主伺服器發生了故障,該模式可以保證Slave從伺服器順利更新為Master主伺服器繼續提供服務,以此提高系統的高可用性。雖然哨兵模式比主從模式提高了不少系統的高可用性,但是該模式不能水準擴容,不能動态的增、删節點,這也是限制哨兵模式廣泛應用的主要原因。Redis也看到了這個情況,所在在Redis的3.x以後的版本提供了一個更加強大叢集模式,那就是Cluster叢集模式,這個模式也是我們下一篇文章的主題。