Redis簡介三(哨兵sentinel,故障轉移)


在上一章節,我們已經簡單的聊過了哨兵以及它的功能,這一章我們詳細介紹它的運行機制

啓動哨兵

跟上一章一樣,演示一個小demo,現在是在牀上換了個筆記本,屏幕比較小,圖片看不清楚的自己放大。

  1. 首先我們啓動兩個Redis實例6379和6380,同時將6379設置爲master,6380設置爲slave,具體代碼以及實例就不再重複演示了,不懂的去看上一章節。
  2. 我們需要給master設置三個哨兵,在docker中,我們需要進入master容器的內部來啓動哨兵:
docker exec -ti master /bin/bash  // 用於進入master容器內部
cd /        			// 進入當前容器的根目錄
touch sentinel1.conf    //創建第一個哨兵的啓動配置文件
touch sentinel2.conf    //創建第二個哨兵的啓動配置文件
touch sentinel3.conf    //創建第三個哨兵的啓動配置文件

ok,我們現在已經成功的在容器內部創建出了3個哨兵的配置文件了
下面我們對配置文件進行配置,主要有兩項,一個是哨兵的端口號,一個是設置需要監控哪一個Redis實例。以其中一個文件爲例,另外兩個配置,只需要將端口號改掉即可:

vim sentinel1.conf    // 用vim打開當前的配置文件
port 26379       //將哨兵端口號設置爲26379
sentinel monitor master 172.17.0.02  6379 2  
//設置需要監控的實例別名,對應的ip是172.0.0.2 ,端口號是6379,而將這個主服務器判斷爲失效至少需要 2 個 Sentinel 同意    

將三個配置文件按照如上配置,依次保存。
ps:我本地的docker是沒有vim的需要先進行安裝

apt-get update
apt-get install vim -y
  1. 啓動哨兵
redis--sentinel  /sentinel1.conf     // 啓動哨兵1
redis--sentinel  /sentinel2.conf     // 啓動哨兵2
redis--sentinel  /sentinel3.conf     // 啓動哨兵3

至此,我們就將一個master,一個slave,三個哨兵的環境建立起來了:
在這裏插入圖片描述

自動發現 Sentinel 和從服務器

從上面的啓動界面,我們就可以看到,當哨兵服務啓動之後,就已經檢測到了master(172.17.0.2)以及slave(172.17.0.3)。

結合上一章節,我們可以知道,哨兵在發起災備救援之前,是需要進行投票的,也就是說,每個哨兵之間是需要進行通信的,可我們從啓動的過程可以看到,我們並沒有設置任何哨兵之間通信的信息。

其實哨兵之間的通信,是基於Redis的發佈訂閱功能實現的:

psubscribe *     // 查看當前Redis中所有的訂閱消息

在這裏插入圖片描述
通過查看消息,我們可以看到有一個叫”hello“的頻道通信非常頻繁,是的,你沒有猜錯,所有啓動了的哨兵,都會訂閱這個消息頻道,具體如下:

  • 每個 Sentinel 會以每兩秒一次的頻率, 通過發佈與訂閱功能, 向被它監視的所有主服務器和從服務器的 sentinel:hello 頻道發送一條信息, 信息中包含了 Sentinel 的 IP 地址、端口號和運行 ID (runid)。
  • 每個 Sentinel 都訂閱了被它監視的所有主服務器和從服務器的 sentinel:hello 頻道, 查找之前未出現過的 sentinel (looking for unknown sentinels)。 當一個 Sentinel 發現一個新的 Sentinel 時, 它會將新的 Sentinel 添加到一個列表中, 這個列表保存了 Sentinel 已知的, 監視同一個主服務器的所有其他 Sentinel 。
  • Sentinel 發送的信息中還包括完整的主服務器當前配置(configuration)。 如果一個 Sentinel 包含的主服務器配置比另一個 Sentinel 發送的配置要舊, 那麼這個 Sentinel 會立即升級到新配置上。
  • 在將一個新 Sentinel 添加到監視主服務器的列表上面之前, Sentinel 會先檢查列表中是否已經包含了和要添加的 Sentinel 擁有相同運行 ID 或者相同地址(包括 IP 地址和端口號)的 Sentinel , 如果是的話, Sentinel 會先移除列表中已有的那些擁有相同運行 ID 或者相同地址的 Sentinel , 然後再添加新 Sentinel 。

定期任務

  • 每個 Sentinel 以每秒鐘一次的頻率向它所知的master、slave以及其他 Sentinel 實例發送一個 PING 命令。
  • 如果一個實例距離最後一次有效回覆 PING 命令的時間超過 預設值, 那麼這個實例會被 Sentinel 標記爲主觀下線。
  • 如果一個主服務器被標記爲主觀下線, 那麼正在監視這個主服務器的所有 Sentinel 要以每秒一次的頻率確認主服務器的確進入了主觀下線狀態。
  • 如果一個主服務器被標記爲主觀下線, 並且有足夠數量的 Sentinel (至少要達到配置文件指定的數量)在指定的時間範圍內同意這一判斷, 那麼這個主服務器被標記爲客觀下線。
  • 一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有主服務器和從服務器發送 INFO 命令。 當一個主服務器被 Sentinel 標記爲客觀下線時, Sentinel 向下線主服務器的所有從服務器發送 INFO 命令的頻率會從 10 秒一次改爲每秒一次。
  • 當沒有足夠數量的 Sentinel 同意主服務器已經下線, 主服務器的客觀下線狀態就會被移除。 當主服務器重新向 Sentinel 的 PING 命令返回有效回覆時, 主服務器的主觀下線狀態就會被移除。

名詞解釋

  • 主觀下線:
    單個 Sentinel 實例對服務器做出的下線判斷。
  • 客觀下線:
    多個 Sentinel 實例在對同一個服務器做出 SDOWN 判斷

故障轉移

  • 發現主服務器已經進入客觀下線狀態。
  • 第一個發現master下線的哨兵,對自身的當前紀元進行自增, 並嘗試在這個紀元中當選。
    如果當選失敗, 那麼在設定的故障遷移超時時間的兩倍之後, 重新嘗試當選。 如果當選成功, 那麼執行以下步驟。
  • 選出一個從服務器,並將它升級爲主服務器。
  • 向被選中的從服務器發送 SLAVEOF NO ONE 命令,讓它轉變爲主服務器。
  • 通過發佈與訂閱功能, 將更新後的配置傳播給所有其他 Sentinel , 其他 Sentinel 對它們自己的配置進行更新。
  • 向其他slave發送 SLAVEOF 命令, 讓它們去複製新的主服務器。
  • 當所有slave都已經開始複製新的主服務器時, 領頭 Sentinel 終止這次故障遷移操作。

Sentinel leader 選舉新的主服務器:

  • 在失效主服務器屬下的從服務器當中, 那些被標記爲主觀下線、已斷線、或者最後一次回覆 PING 命令的時間大於五秒鐘的從服務器都會被淘汰。
  • 在失效主服務器屬下的從服務器當中, 那些與失效主服務器連接斷開的時長超過 down-after 選項指定的時長十倍的從服務器都會被淘汰。
  • 在經歷了以上兩輪淘汰之後剩下來的從服務器中, 我們選出複製偏移量(replication offset)最大的那個從服務器作爲新的主服務器; 如果複製偏移量不可用, 或者從服務器的複製偏移量相同, 那麼帶有最小運行 ID 的那個從服務器成爲新的主服務器。

Sentinel 使用 Raft 算法來選leader , 確保在一個給定的紀元(epoch)裏, 只有一個leader, 並且每個 Sentinel 在同一個紀元中只會對一個leader進行投票。更高的配置紀元總是優於較低的紀元, 因此每個 Sentinel 都會主動使用更新的紀元來代替自己的配置。

參考文檔

http://redis.cn/topics/sentinel.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章