紙上得來終覺淺,絕知此事要躬行。html
Sentinel是Redis的高可用的解決方案,有多個Sentinel實例構成Sentinel系統。系統能夠監視任意多個主服務器以及這些主服務器下的從服務器,當被監視的主服務器進入下線狀態時,自動將下線的主服務屬下的從服務器升級爲新的主服務器,而後由新的主服務器替代下線主服務器繼續處理命令請求。redis
下圖展現了一個Sentinel系統監視服務器的例子:sql
假設此時,主服務器Master因爲某種緣由意外宕機下線,那麼從服務器slave對主服務器的複製操做將被終止。而且Sentinel系統會察覺到Master已經下線。服務器
當Master長時間處於下線,Sentinel系統將會對Master進行執行故障轉移,以後Sentinel系統會在Master屬下的從服務器挑選出一個做爲新的主服務器,而且先其餘slave發送複製指令,讓他們重新的服務器開始複製。網絡
當某個時間舊Master從新上線時,Sentinel系統會將它設置爲新服務器的從服務器。異步
注意:以上的Sentinel系統中任意一臺Sentinel都會監視全部的服務器3d
redis-sentinel /path/to/sentinel.conf
redis-server /path/to/sentinel.conf --sentinel
配置項 | 示例 | 說明 |
---|---|---|
sentinel auth-pass <服務器名稱> |
sentinel auth-pass mymaster ydongy |
鏈接服務器口令 |
sentinel down-after-milliseconds <自定義服務名稱><主機地址><端口><主從服務器總量> |
sentinel monitor mymaster 1127.0.0.1 6379 1 |
設置哨兵監聽的主服務器信息,最後的參數決定了最終參與選舉的服務器數量 |
sentinel parallel-syncs <服務名稱><服務器數(整數)> |
sentinel parallel-syncs mymaster 1 |
指定同時進行主從的slave數量,數值越大,要求網絡資源越高,要求約小,同步時間約長 |
sentinel failover-timeout <服務名稱><毫秒數(整數)> |
sentinel failover-timeout mymaster 9000 |
指定出現故障後,故障切換的最大超時時間,超過該值,認定切換失敗,默認3分鐘 |
sentinel notification-script <服務名稱><腳本路徑> |
服務器沒法正常聯通時,設定的執行腳本,一般調試使用。 |
Sentinel啓動時會經過配置建立與指定主服務器的網絡鏈接,Sentinel將成爲主服務器的客戶端,能夠向主服務器發送命令,而且從命令的回覆中獲取相關服務器的信息。調試
對於每一個被Sentinel監視和主服務器來講,Sentinel會建立兩個異步網絡鏈接:code
__Sentinel__:hello
頻道Sentinel默認會每十秒發送一次info
命令,經過分析info
命令的回覆獲取主服務器當前信息以及根據當前主服務器下的從服務器ip
和port
地址信息,自動的發現從服務器。並保存在一個鍵爲:ip:port
,值爲從服務器的實例結構的字典當中。一樣也會建立鏈接到從服務器的命令鏈接和訂閱鏈接。整個結構以下圖:server
在建立命令以後,Sentinel在默認狀況下,一樣也會每十秒一次的頻率經過命令鏈接向從服務器發送info
命令,得到從服務器的詳細信息,根據這些信息,會對以前的從服務器實例結構進行更新。
在默認狀況下,Sentinel會以每兩秒一次的頻率,經過命令鏈接向全部被監視的主服務器和從服務器發送命令到__Sentinel__:hello
頻道:
PUBLISH __Sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"
s_
表示Sentinel自己信息m_
表示主服務的信息經過命令鏈接向__Sentinel__:hello
頻道發送的消息,同時又會被訂閱鏈接
從頻道中獲取出來,包括其餘在__Sentinel__:hello
頻道中的Sentinel一樣也會接受到該信息(包括髮送者本身)。舉個例子,以下圖:
因爲每一個Sentinel都會發送消息,也就是說任何一個Sentinel都會接受到本身以及其餘Sentinel發送的消息,而且消息中含有Sentinel的信息,因此每一個Sentinel都會把本身以及其餘的Sentinel的信息保存在字典當中,鍵是ip:port
,值是一個Sentinel實例結構。當之後每次接受到消息,更新保存的信息,防止有宕機的Sentinel或者新添加的Sentinel。
上一節說了在Sentinel向服務器經過命令鏈接發送信息,會被訂閱鏈接接受到消息,若是發現一個字典當中不存在當前Sentinel,會爲當前Sentinel建立相應的實例結構。
其實,同時會建立一個命令鏈接,而新Sentinel也會鏈接到這個Sentinel,至關於兩兩相連,以下圖所示:
在默認狀況下,Sentinel會一秒一次的頻率向全部與它建立命令鏈接的服務器(包括:主服務器,從服務器,其餘Sentinel)發送PING
命令,經過實例的返回恢復來判斷實例時候在線。
發送PING
命令回覆分爲兩種:
+PONG
-LOADING
-MASTERDOWN
最開始啓動Sentinel的時候,咱們在配置文件中配置了一個down-after-milliseconds
的參數,若是在當前參數範圍內沒有一次有效恢復,那麼當前Sentinel就認爲該服務器主觀下線,固然還可能存在多個Sentinel配置的時間大小不一樣,例如:
sentinel monitor master 127.0.0.1 6379 2 sentinel down-after-milliseconds master 60000
sentinel monitor master 127.0.0.1 6379 2 sentinel down-after-milliseconds master 20000
那麼當master的斷線時長超過20000毫秒以後,sentinel-2會判斷該服務器主觀下線,可是Sentinel-1認爲master處於在線狀態,以後當master斷線60000毫秒以後,Sentinel-1和Sentinel-2才都會認爲master進入主觀下線狀態。結合圖查看一下:
當Sentinel將一個主服務器判斷爲主觀下線以後,爲了確保主服務器真正的下線,當前的Sentinel會先其餘監視該服務器的Sentinel進行詢問,看他們是否也認爲主服務器進入下線狀態,當Sentinel從其餘Sentinel哪裏接受到足夠數量的如下線判斷以後,Sentinel就會將服務斷定爲客觀下線,以後便進行故障轉移。
經過發送以下命令進行詢問其餘Sentinel:
SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>
ip
:主服務器IP地址port
:主服務器端口號current_epoch
:Sentinel當前的配置紀元runid
:能夠爲*
表示僅僅檢測主服務器的客觀下線狀態,或者是Sentinel的運行ID用於選舉領頭Sentinel接受源Sentinel命令回覆:
down_state
:返回接受者Sentinel的對主服務器的檢查結果,1:下線,0:未下線leader_runid
:能夠是*
表示僅僅檢測主服務器的下線狀態,或者接受者Sentinel的運行ID用於選舉領頭Sentinelleader_epoch
:接受者Sentinel的認爲領頭Sentinel的配置紀元例如:
1 * 0
那麼說明接受者Sentinel也贊成主服務已下線。整個過程如圖所示:
客觀下線的判斷條件是經過配置中sentinel monitor host6379 127.0.0.1 6379 2
最後一個參數決定,例如當前爲2,意味着若是全部的Sentinel只要有兩個認爲主服務器下線,那麼當前Sentinel纔會將主服務判斷爲客觀下線。
在一個主服務器被判斷爲客觀下線時,監視這個下線主服務器的一個Sentinel會進行協商,選出一個領頭Sentinel去進行故障轉移操做。
選取領頭Sentinel規則和方法:
leader_epoch
,若是接受者Sentinel回覆的參數是發送者Sentinel的運行ID,就代表當前Sentinel投給了發送者Sentinel這一票,只要有一個Sentinel的票數大於總票的一半以上,那麼那個Sentinel就會成爲領頭Sentinel在選舉出領頭Sentinel以後,領頭Sentinel將對已下線的主服務器執行故障轉移操做,包含如下步驟:
從服務器挑選規則:將全部從服務器保存到一個列表,對列表進行過濾:
info
命令的選出以後發送命令sqlveof no one
,而後接着每秒一次發送info
命令,分析回覆信息,直到被選中的從服務器的role
爲master
,表示成功升級爲主服務器。以後修改其餘從服務器的複製目標,發送命令slaveof ip port
(ip是升級後的服務器ip,port是升級後服務器的port)。
當舊服務器從新上線,Sentinel會向它發送slaveof
命令,讓他成* 爲新的主服務器的從服務器。
sentinel-1 | sentinel-2 | sentinel-3 |
---|---|---|
port 26379 sentinel monitor host6379 127.0.0.1 6379 2 sentinel down-after-milliseconds host6379 60000 sentinel failover-timeout host6379 180000 sentinel parallel-syncs host6379 1 |
port 26380 sentinel monitor host6379 127.0.0.1 6379 2 sentinel down-after-milliseconds host6379 60000 sentinel failover-timeout host6379 180000 sentinel parallel-syncs host6379 1 |
port 26381 sentinel monitor host6379 127.0.0.1 6379 2 sentinel down-after-milliseconds host6379 60000 sentinel failover-timeout host6379 180000 sentinel parallel-syncs host6379 1 |
port
:配置哨兵端口
sentinel monitor host6379 127.0.0.1 6379 2
:指示 Sentinel 去監視一個名爲 mymaster 的主服務器, 這個主服務器的 IP 地址爲 127.0.0.1 , 端口號爲 6379 , 而將這個主服務器判斷爲失效至少須要 2 個 Sentinel 贊成 (只要贊成 Sentinel 的數量不達標,自動故障遷移就不會執行)。
down-after-milliseconds
:選項指定了 Sentinel 認爲服務器host6379已經斷線所需的毫秒數。若是服務器在給定的毫秒數以內, 沒有返回 Sentinel 發送的 PING 命令的回覆, 或者返回一個錯誤, 那麼 Sentinel 將這個服務器標記爲主觀下線。 只有在足夠數量的 Sentinel 都將一個服務器標記爲主觀下線以後, 服務器纔會被標記爲客觀下線,這時自動故障遷移纔會執行。
服務器對 PING 命令的有效回覆能夠是如下三種回覆的其中一種:
若是服務器返回除以上三種回覆以外的其餘回覆, 又或者在指定時間內沒有回覆 PING 命令, 那麼 Sentinel 認爲服務器返回的回覆無效(non-valid)。
注意, 一個服務器必須在 master-down-after-milliseconds 毫秒內, 一直返回無效回覆纔會被 Sentinel 標記爲主觀下線。
舉個例子, 若是 master-down-after-milliseconds 選項的值爲 30000 毫秒(30 秒), 那麼只要服務器能在每 29 秒以內返回至少一次有效回覆, 這個服務器就仍然會被認爲是處於正常狀態的。
parallel-syncs
: 選項指定了在執行故障轉移時, 最多能夠有多少個從服務器同時對新的主服務器進行同步, 這個數字越小, 完成故障轉移所需的時間就越長。