天天看點

7.4 Redis哨兵之實作原理

1.三個定時任務

(1).每10秒info

Sentinel每10秒會對master執行info操作,擷取master的slave節點資訊,Sentinel拿到slave資訊之後,每10秒也會執行info操作,去發現slave的從節點。起到Sentinel感覺Redis的作用。

7.4 Redis哨兵之實作原理

(2).每2秒釋出訂閱

Sentinel之間通過master節點的_sentinel_:hello頻道來交換資訊,即每個Sentinel都會訂閱_sentinel_:hello,然後向其釋出資訊以此來達到交換資訊的目的。如果有新的Sentinel加入,也會訂閱_sentinel_:hello并釋出消息。起到Sentinel感覺Sentinel的作用。

7.4 Redis哨兵之實作原理

(3).每1秒ping

每個Sentinel每秒會對其他Sentinel和Redis執行ping指令做心跳檢測,以此作為其是否存活的判斷依據。

7.4 Redis哨兵之實作原理

2.主觀下線和客觀下線

(1).主觀下線(偏見)

每個Sentinel節點會每隔1秒對主節點、從節點、其他Sentinel節點發送ping指令做心跳檢測,當這些節點超過配置的down-after-milliseconds時間而未進行有效回複,Sentinel節點就會認為該節點存在故障,這個行為叫做主觀下線,其配置如下。

sentinel down-after-milliseconds  mymaster 30000      

(2).客觀下線(共識)

當Sentinel主觀下線的節點是主節點時,該Sentinel節點會通過sentinel is-master-down-by-addr指令向其他Sentinel節點詢問對主節點的判斷,當超過quorum個數時,Sentinel節點認為主節點确實有問題,這時該Sentinel節點會做出客觀下線的決定,即是大部分Sentinel節點都對主節點的下線做了同意的判定,這就是客觀下線,其配置如下。

#sentinel monitor <masterName> <ip> <port> <quorum>
sentinel monitor mymaster 127.0.0.1 7000 2

#sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>
sentinel is-master-down-by-addr 127.0.0.1 6379 0 *      
  • ip:主節點IP
  • port:主節點端口。
  • current_epoch:目前配置紀元。
  • runid:此參數有兩種類型,不同類型決定了此API作用的不同。當runid等于“*”時,作用是Sentinel節點直接交換對主節點下線的判定。

    當runid等于目前Sentinel節點的runid時,作用是目前Sentinel節點希望目标Sentinel節點同意自己成為上司者的請求。

如sentinel-1節點對主節點做主觀下線後,會向其餘Sentinel節點(如sentinel-2和sentinel-3 節點)發送指令sentinel is-master-down-by-addr 127.0.0.1 6379 0 *,來詢問它們的看法,傳回結果包含如下三個參數。

  • down_state:目标Sentinel節點對于主節點的下線判斷,1是下線,0是線上。
  • leader_runid:當leader_runid等于“*”時,代表傳回結果是用來做主節點是否不可達的。當leader_runid等于具體的runid,代表目标節點統一runid稱為上司者。
  • leader_epoch:上司者紀元。

3.上司者選舉

(1).簡介

  • 原因:隻需要一個Sentinel節點完成故障轉移
  • 方式:通過Sentinel的is-master-down-by-addr指令來競選上司者

(2).流程

  • 每個做完主觀下線的Sentinel節點向其他Sentinel節點發送is-master-down-by-addr指令,要求将自己設定為上司者。
  • 收到指令的Sentinel節點,如果沒有同意過其他Sentinel節點發送的is-master-down-by-addr指令,将同意該請求,否則拒絕。
  • 如果該Sentinel節點發現自己的票數已經大于等于max(quorum,num(sentinels)/2+1),那麼它将成為上司者。
  • 如果此過程沒有選舉出上司者,将等待一段時間重新進行選舉。

(3).上司者選舉示例

  • 假如Sentinel-1最先完成了主觀下線,它會向Sentinel-2和Sentinel-3發送is-master-down-by-addr指令,Sentinel-2和Sentinel-3沒有同意過其它節點,是以會同意選Sentinel-1為上司者。Sentinel-此時已經拿到2張投票,滿足了大于等于max(quorum,num(sentinels)/2+1)=2的條件,是以此時Sentinel-1成為上司者。
  • 假如Sentinel-2接着完成了主觀下線,由于每個Sentinel節點隻有一票以及Sentinel-2和Sentinel-3把票投給了Sentinel-1,是以當Sentinel-2向Sentinel-1和Sentinel-3索要投票時,隻能擷取Sentinel-1的一票。
  • 最後,Sentinel-2接着完成了主觀下線,由于Sentinel-2和Sentinel-3把票投給了Sentinel-1,Sentinel-1把票投給了Sentinel-2,是以Sentinel-3沒有獲得選票。
  • 從slave節點中選出一個“合适的”節點作為新的master節點。
  • 對上面的slave節點執行slaveof no one指令讓其稱為master節點。
  • 向剩餘的slave節點發送切主指令,讓他們稱為新master節點的slave節點,複制規則和parallel-syncs參數有關。
  • 更新對原來master節點配置為slave,并保持着對其“關注”,當其恢複後指令它去複制新的master節點。
  • 選擇slave-priority(slave節點優先級)最高的sqlave節點,如果存在則傳回,不存在則繼續。
  • 選擇複制偏移量最大的slave節點(複制的最完整),如果存在則傳回,不存在則繼續。
  • 選擇runid最小的從節點(最早的節點)。

繼續閱讀