redis 哨兵機制

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

  • a)選出合適從節點。
  • b)晉升選出的從節點爲主節點。
  • c)命令其他從節點複製新的主節點。
  • d)等待原主節點恢復後命令它去複製新的主節點。

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節點的日誌便可):
redis 哨兵機制
上面標註的信息,就是一次故障轉移產生的日誌,能夠看到以前的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的主節點狀態以及相關的統計信息
返回結果以下:
redis 哨兵機制
其餘相關指令:

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)有兩個不一樣的概念:

  • 主觀下線(Subjectively Down,簡稱 sdown)指的是單個Sentinel實例對服務器作出的下線判斷。
  • 客觀下線(Objectively Down,簡稱 sdown)指的是多個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 命令的有效回覆能夠是如下三種回覆的其中一種:

  • 返回 +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命令返回有效回覆時,主服務器的主觀下線狀態就會被移除。

其餘可參考官方文檔

相關文章
相關標籤/搜索