Redis的哨兵機制存在的意義就是當主從架構中,master發生宕機,無需人工干預,自動實現故障轉移。
官方文檔
Redis哨兵能幹什麼?html
Redis的Sentinel系統用於管理多個Redis示例,該系統執行如下三個任務:redis
- 監控(Monitoring): Sentinel 會不斷地檢查你的master和slave是否運做正常。
- 提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 能夠經過 API 向管理員或者其餘應用程序發送通知。
- 自動故障遷移(Automatic failover): 當一個主服務器不能正常工做時, Sentinel 會開始一次自動故障遷移操做, 它會將失效master的其中一個slave升級爲新的master,並讓失效master的其餘slave改成複製新的master;當客戶端試圖鏈接失效的master時,集羣也會向客戶端返回新master的地址, 使得集羣可使用新master代替失效服務器。
環境以下算法
hostname | IP | server |
---|---|---|
redis1 | 192.168.171.150 | Redis(master) |
redis2 | 192.168.171.151 | Redis(slave) |
redis3 | 192.168.171.152 | Redis(slave) |
注:須要保證各個節點的redis服務正常運行,關於部署redis能夠參考博文:Redis 5.0部署
配置主從複製
在兩臺slave節點上執行如下命令,指定主機redis01爲master數據庫
127.0.0.1:6379> slaveof 192.168.171.151 6379
在redis01主機上查看鏈接的slave服務器
127.0.0.1:6379> info replication # 執行此指令,查看複製信息 # Replication role:master connected_slaves:2 # 如下是鏈接的slave信息 slave0:ip=192.168.171.152,port=6379,state=online,offset=70,lag=1 slave1:ip=192.168.171.153,port=6379,state=online,offset=70,lag=0 .............................
驗證主從複製markdown
# redis01節點: 127.0.0.1:6379> set test slave_copy OK # 其餘節點肯定新建的數據已同步 127.0.0.1:6379> get test "slave_copy"
至此,主從複製完成。架構
若要了解主從複製更多原理,能夠參考博文:redis主從複製詳解
配置Sentinel節點
如下操做在其中一個節點進行便可(我這裏在redis01節點上)。tcp
[root@redis1 conf]# pwd /usr/local/redis/conf # 拷貝一份sentinel的配置文件到當前目錄 [root@redis1 conf]# cp ~/redis-5.0.5/sentinel.conf . # 修改後的配置文件以下: [root@redis1 conf]# egrep -v '^$|^#' sentinel.conf bind 0.0.0.0 # 監聽地址 port 26379 #監聽端口 daemonize yes # 開啓守護進程 pidfile /var/run/redis-sentinel.pid # 指定pid文件 logfile "/usr/local/redis/data/sentinel.log" # 指定日誌文件 dir /tmp # 指定工做目錄 # 下面的配置稍後解釋 sentinel monitor mymaster 192.168.171.151 6379 2 sentinel down-after-milliseconds mymaster 60000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes # 發送修改後的配置文件到其餘redis節點 [root@redis1 conf]# for i in 152 153;do scp sentinel.conf root@192.168.171.${i}:/usr/local/redis/conf/;done
其餘參數解釋
sentinel monitor mymaster 192.168.171.151 6379 2:
上面這行配置是指示sentinel去監視一個名爲mymaster(這個名稱自定義)的主服務器,這個master的IP地址爲192.168.171.151,端口號爲6379,而將這個master判斷爲失效至少須要2個sentinel贊成(只要贊成sentinel的數量不達標,自動故障遷移就不會執行。這個數值的由來:sentinel節點的總數 / 2 + 1,也就是sentinel節點的半數以上是最好的)。
sentinel down-after-milliseconds mymaster 60000
上面的配置意思爲:若是mymaster這個主節點在指定的60000毫秒內,沒有返回sentinel發送的ping命令的回覆,或者返回一個錯誤,那麼sentinel將這個服務器標記爲主觀下線。ide
不過只有一個 Sentinel 將服務器標記爲主觀下線並不必定會引發服務器的自動故障遷移: 只有在足夠數量的 Sentinel都將一個服務器標記爲主觀下線以後,服務器纔會被標記爲客觀下線,這時自動故障遷移纔會執行。將服務器標記爲客觀下線所需的 Sentinel 數量由對主服務器的配置決定。
sentinel parallel-syncs mymaster 1
指定了在執行故障轉移時, 最多能夠有多少個從服務器同時對新的主服務器進行同步, 這個數字越小, 完成故障轉移所需的時間就越長。可是避免了故障轉移後,多個slave都去同步新的master發生的阻塞,能夠根據實際狀況來設置這個值,好比上面設置值爲1,則表示發生故障轉移後,一次只能有一個slave去同步新master的數據,這樣能夠避免阻塞。
sentinel failover-timeout mymaster 180000
sentinel failover-timeout Sentinel failover-timeout failover-timeout一般被解釋成故障轉移超時時間,但實際上它做用於故障轉移的各個階段:3d
failover-timeout的做用具體體如今四個方面:
- 若是Redis Sentinel對一個主節點故障轉移失敗,那麼下次再對該主節點作故障轉移的起始時間是failover-timeout的2倍。
- 在b)階段時,若是Sentinel節點向a)階段選出來的從節點執行slaveof no one一直失敗(例如該從節點此時出現故障),當此過程超過failover-timeout時,則故障轉移失敗。
- 在b)階段若是執行成功,Sentinel節點還會執行info命令來確認a)階段選出來的節點確實晉升爲主節點,若是此過程執行時間超過failover-timeout時,則故障轉移失敗。
- 若是c)階段執行時間超過了failover-timeout(不包含複製時間),則故障轉移失敗。注意即便超過了這個時間,Sentinel節點也會最終配置從節點去同步最新的主節點。
sentinel auth-pass
若是Sentinel監控的主節點配置了密碼, sentinel authpass配置經過添加主節點的密碼,防止Sentinel節點對主節點沒法監控。
啓動sentinel
如下操做須要在全部節點執行。
[root@redis1 conf]# pwd # 肯定當前路徑 /usr/local/redis/conf [root@redis1 conf]# redis-sentinel sentinel.conf # 啓動sentinel,sentinel.conf爲哨兵機制的配置文件名 [root@redis1 conf]# ss -anput | grep 26379 # 哨兵的監聽端口爲26379 tcp LISTEN 0 511 *:26379 *:* users:(("redis-sentinel",pid=40904,fd=6))
查看sentinel啓動後配置文件的變化
[root@redis1 conf]# egrep -v '^$|^#' sentinel.conf bind 0.0.0.0 port 26379 daemonize yes pidfile "/var/run/redis-sentinel.pid" logfile "/usr/local/redis/data/sentinel.log" dir "/tmp" sentinel myid 10d5c185e309cd1fd2540b8fe2b3a07748b72eef sentinel deny-scripts-reconfig yes sentinel monitor mymaster 192.168.171.151 6379 2 sentinel down-after-milliseconds mymaster 60000 sentinel config-epoch mymaster 0 protected-mode no sentinel leader-epoch mymaster 0 # 能夠發現它已經經過master的info信息,採集到了其餘兩個slave節點的信息 sentinel known-replica mymaster 192.168.171.153 6379 sentinel known-replica mymaster 192.168.171.152 6379 sentinel known-sentinel mymaster 192.168.171.152 26379 f446083dcdbf99a9253efcc2a5197094e9d75d35 sentinel known-sentinel mymaster 192.168.171.153 26379 fafa402e43edf1ea5b8aebaf5685c07e5194246f sentinel current-epoch 0
驗證故障轉移效果
當我此時手動將當前的master進行shutdown關閉後,sentinel的日誌顯示以下(任意一個sentinel節點的日誌便可):
上面標註的信息,就是一次故障轉移產生的日誌,能夠看到以前的slave節點192.168.171.152成爲了新主,此時能夠去redis2和redis3主機上查看確認當前的主.
# 主機redis2 127.0.0.1:6379> info replication # Replication role:master # redis02當前爲master connected_slaves:1 slave0:ip=192.168.171.153,port=6379,state=online,offset=98179,lag=0 # 主機redis3 127.0.0.1:6379> info replication # Replication role:slave master_host:192.168.171.152 # 當前主爲redis02的地址 master_port:6379 master_link_status:up
從新啓動redis1實例
[root@redis1 ~]# redis-server /usr/local/redis/conf/redis.conf [root@redis1 ~]# redis-cli # 登陸到數據庫 127.0.0.1:6379> info replication # 查看複製信息 # Replication role:slave master_host:192.168.171.152 # 能夠發現自動指向redis02節點做爲了master master_port:6379 master_link_status:up
這就是完整的故障轉移效果
sentinel維護命令
Sentinel節點是一個特殊的Redis節點,它有本身專屬的API,下面將分別展現。
登陸到哨兵監聽的26379端口
[root@redis1 ~]# redis-cli -p 26379 # 使用redis-cli指令便可登陸
127.0.0.1:26379> sentinel master mymaster # 查看mymaster的主節點狀態以及相關的統計信息
返回結果以下:
其餘相關指令:
127.0.0.1:26379> sentinel slaves mymaster # 查看指定的從節點狀態及相關統計信息 127.0.0.1:26379> sentinel get-master-addr-by-name mymaster # 返回主節點的IP和端口 127.0.0.1:26379> sentinel failover mymaster # 對指定進行強制故障轉移(他會將master角色自動轉移到當前任意一個slave,沒有和其餘sentinel節點協商),當故障轉移完成以後,其餘的sentinel節點按照故障轉移的結果更新自身配置。 127.0.0.1:26379> sentinel ckquorum mymaster # 檢測當前主節點的哨兵是否到達quorum的個數。 127.0.0.1:26379> sentinel flushconfig # 將sentinel節點的配置信息強制寫道磁盤上 127.0.0.1:26379> sentinel remove mymaster # 取消當前sentinel節點對於指定主節點的監控
redis哨兵機制中的其餘概念
主觀下線和客觀下線
Redis的Sentinel中關於下線(down)有兩個不一樣的概念:
服務器對 PING 命令的有效回覆能夠是如下三種回覆的其中一種:
- 返回 +PONG 。
- 返回 -LOADING 錯誤。
- 返回 -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 在將它們判斷爲下線前不須要進行協商, 因此從服務器或者其餘 Sentinel 永遠不會達到客觀下線條件。
只要一個Sentinel發現某個主服務器進入了客觀下線狀態, 這個Sentinel就可能會被其餘 Sentinel 推選出,並對失效的主服務器執行自動故障遷移操做。
每一個 Sentinel 都須要按期執行的任務
- 每一個Sentinel以每秒鐘一次的頻率向它所知的主服務器、從服務器以及其餘Sentinel實例發送一個PING命令。
- 若是一個實例(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 那麼這個實例會被Sentinel 標記爲主觀下線。 一個有效回覆能夠是: +PONG 、 -LOADING 或者-MASTERDOWN 。
- 若是一個主服務器被標記爲主觀下線, 那麼正在監視這個主服務器的全部 Sentinel要以每秒一次的頻率確認主服務器的確進入了主觀下線狀態。
- 若是一個主服務器被標記爲主觀下線, 而且有足夠數量的 Sentinel (至少要達到配置文件指定的數量)在指定的時間範圍內贊成這一判斷,那麼這個主服務器被標記爲客觀下線。
- 在通常狀況下,每一個Sentinel會以每 10 秒一次的頻率向它已知的全部主服務器和從服務器發送INFO命令。 當一個主服務器被Sentinel標記爲客觀下線時,Sentinel向下線主服務器的全部從服務器發送INFO命令的頻率會從10秒一次改成每秒一次。
- 當沒有足夠數量的Sentinel贊成主服務器已經下線,主服務器的客觀下線狀態就會被移除。當主服務器從新向 entinel的PING命令返回有效回覆時,主服務器的主觀下線狀態就會被移除。
其餘可參考官方文檔