1. 程式人生 > 其它 >Redis Sentinel 學習筆記

Redis Sentinel 學習筆記

  redis快取在我們的日常編碼中經常會使用到,幾乎是不可或缺的一環。但如果線上的redis主伺服器掛了怎麼辦,等待專案監控報警然讓運維同學切換主備伺服器來解決這個問題?當然可以,最好是把監控和主從伺服器切換實現自動化,就能實現快速響應,也能減少人工的介入。redis實現了該功能,就是redis sentinel(哨兵);

 

一、sentinel是什麼

  redis sentinel(哨兵)是一種redis的高可用解決方案,通過一個或者多個sentinel服務組成redis的sentinel叢集,監控redis服務的狀態。當被監視的redis主伺服器出現問題導致下線的時候,sentinel服務則將有問題的主伺服器進行降級成從伺服器,將主伺服器的從伺服器升級為主伺服器。通過這種方式,保證redis叢集的高可用。

  當redis叢集裡的master出現宕機的時候,sentinel系統會檢測到當前的master伺服器已經沒有響應,需要進行故障轉移處理,此時sentinel系統會選出一個sentinel伺服器進行以下操作

  1. 從這個master底下的伺服器下slave裡挑選一臺成為新的主伺服器
  2. sentinel會發出指令,令這個master下的其他slave伺服器成為新的master伺服器的slave
  3. 監視已經下線的原master,當這個master伺服器重新上線時,將其設定為新的master伺服器的slave

  redis sentinel伺服器是一種執行在特殊模式下的redis伺服器,它跟常見redis伺服器的區別

  • 是兩者使用不同程式碼,因為功能不同,預設埠因為不一樣
  • sentinel啟動時候不需要載入RDB檔案或者AOF還原資料狀態
  • 兩種伺服器支援的命令集不同

 

二、sentinel的狀態資料

  在每一個sentinel服務啟動完成之後,伺服器會初始化一個sentinelState的資料結構,該結構儲存了和sentinel功能有關的狀態。該資料的結構如下圖所示。

  sentinelState主要儲存了欄位包含了 current_epoch表示當前紀元,用於故障轉移。還儲存了master字典,儲存了這個sentinel監控的所有master伺服器,這個字典中key是master伺服器的名字,value是一個SentinelRedisInstance的資料結構,SentinelRedisInstance表示一個master伺服器、slave伺服器或者sentinel伺服器。

  在master伺服器SentinelRedisInstance資料結構中,還儲存兩個字典欄位,一個是salves,一個是sentinels。slaves儲存著這個master對應的salves伺服器。sentinels字典裡儲存著正在監聽這個master的所有哨兵伺服器。

 

三、sentinel資料同步        

   sentinel為了維持sentinelState中的資料,需要跟master和salve進行資料互動,sentinel之間也會進行資料的交換。

  1. sentinl啟動時,會讀取sentinel裡的配置檔案,獲取需要監視的master伺服器,為其建立一個SentinelRedisInstance資料結構,並且加入到sentinelState中。並且為該master伺服器建立兩個連結,分別是命令連結(用於傳送命令和接收命令回覆)和一個訂閱連結(專門訂閱_sentinel_:hello頻道)
  2. sentinel會每10秒向監視的master伺服器傳送一次INFO命令,通過master的回覆來獲取相同的資訊。返回資訊包含master本身的資訊(master本身的runId、伺服器當前role )和該master的salves伺服器資訊(IP地址、埠、伺服器狀態、複製偏移量),sentinel如果發現返回salve沒有儲存在sentinelState裡master裡的salves裡,就會為這個salve建立一個例項,儲存到salves資料結構中,併為其建立命令連結和訂閱連結。
  3. 預設情況下,sentinel會每10秒向監視的salve伺服器傳送INFO命令,從salve伺服器中獲取資訊,包含伺服器的run_id(執行id)、role(角色)、master_host、master_port(隸屬的master伺服器的IP和埠)、master_link_status(主從伺服器的連結狀態)、slave_priority(從伺服器的優先順序)和salve_repl_offset(複製偏移量),sentinel通過該資訊更新salves欄位中的資料資訊
  4. sentinel會向以每兩秒一次的頻率,通過命令連結向所有被監視的主伺服器和從伺服器的_sentinel_:hello頻道傳送命令,因為監聽該伺服器的sentinel同時訂閱_sentinel_:hello頻道,所以當一個sentinel傳送訊息的時候,所有的sentinel能同時收到這個資訊。當sentinel收到這個資訊根據IP埠判斷該資訊由自己傳送則丟棄該訊息。如果不是自己傳送的,則根據訊息裡的引數更新sentinels欄位,並與其他的sentinel建立連結。通過這種方式,讓sentinel感知到監聽該伺服器的其他sentinel,並互相之間建立命令連結。
  5. 預設情況下,sentinel會以每秒一次的頻率,向所有與他建立命令連結的例項(包括主伺服器、從伺服器、其他的sentinel)傳送PING命令來判斷是否是否線上。例項會返回+PONG、-LOADING、-MASTERDOWN三種回覆中的一種。

 

四、故障轉移

  sentinel的故障轉移分為幾個步驟

1、主觀下線:

sentinel配置檔案中,down-after-millseconds選項指定了sentinel判斷一個伺服器進入主觀下線的所需時間,當一個伺服器超過down-after-millseconds時間之內,連續向sentinel返回無效回覆或者不回覆,那麼sentinel會將該伺服器判斷為主觀下線,並將資料結構中的flags屬性中開啟SRI_S_DOWN標識。

2、客觀下線:

當一個sentinet判斷一個伺服器狀態為主觀下線後,會向監視該伺服器的其他sentinel進行詢問,是否其他的sentinel對該伺服器的下線狀態判斷。當收到下線判斷的數量超過了sentinel配置的quorum值,則sentinel將該伺服器判斷為客觀下線。flags狀態值改為SRI_O_DOWN

3、選舉領頭sentinel

當一個Master伺服器被判斷為客觀下線之後,監視這個下線伺服器的各個sentinel會進行協商,選舉一個領頭的sentinel進行故障轉移工作。選舉的方式是通過Raft演算法來實現的,通過時間片分片,採用先到先得的方式獲取選票,當獲取的選票大於等於N/2+1時,該sentinel當選領頭哨兵,對異常的Master伺服器進行故障轉移。

4、挑選新的master伺服器

領頭sentinel從salves伺服器中,過濾已下線、斷線狀態、最近五秒沒有回覆INFO的回覆的伺服器、和已下線master斷開連線超過down-after-millseconds * 10的從伺服器,然後再挑選其中從伺服器中配置優先順序最高的伺服器,如果優先順序相同,則挑選複製偏移量最大的伺服器,如果複製偏移量相同,則根據執行id排序,挑選id最小的從伺服器作為新的master。

5、修改從伺服器複製目標

設定完新的master伺服器之後,領頭sentinel會向其他的從伺服器傳送SLAVEOF命令,讓其他的salve複製新的master,並將舊的master設定為新master的從伺服器,等舊master伺服器上線之後,就對其傳送SALVEOF命令,讓其複製新的Master。

 

當Master掛掉之後,客戶端如何工作

  客戶端來連線叢集時,會首先連線 sentinel,通過 sentinel 來查詢主節點的地址,然後再去連線主節點進行資料互動。當主節點發生故障時,客戶端會重新向 sentinel 要地址,sentinel 會將最新的主節點地址告訴客戶端。客戶端連線池建立新連線時,會去查詢主庫地址,然後跟記憶體中的主庫地址進行比對,如果變更了,就斷開所有連線,重新使用新地址建立新連線。如果是舊的主庫掛掉了,那麼所有正在使用的連線都會被關閉,然後在重連時就會用上新地址。當主從庫進行切換時候,客戶端如果對salve傳送寫命令,會返回ReadOnlyError異常,當客戶端獲捕獲到這個異常,則會將所有舊連線關閉,在後續指令裡建立新的連線。