Redis主從複製的問題
Redis 主從複製 可將 主節點 數據同步給 從節點,從節點此時有兩個作用:
- 一旦 主節點宕機,從節點 作為 主節點 的 備份 可以隨時頂上來。
- 擴展 主節點 的 讀能力,分擔主節點讀壓力。
主從複製 同時存在以下幾個問題:
- 一旦 主節點宕機,從節點 晉升成 主節點,同時需要修改 應用方 的 主節點地址,還需要命令所有 從節點去 複製 新的主節點,整個過程需要 人工干預。
- 主節點 的 寫能力 受到 單機的限制。
- 主節點 的 存儲能力 受到 單機的限制。
- 原生複製 的弊端在早期的版本中也會比較突出,比如:Redis 複製中斷 後,從節點 會發起 psync。此時如果 同步不成功,則會進行 全量同步,主庫 執行 全量備份 的同時,可能會造成毫秒或秒級的 卡頓。
Redis 的 哨兵(Sentinel)深入探究
Redis Sentinel的架構
Redis的哨兵機制就是解決我們以上主從複製存在缺陷(選舉問題),保證我們的Redis高可用,實現自動化故障發現與故障轉移。
該系統執行以下三個任務:
監控:哨兵會不斷檢查你的主服務器和從服務器是否運作正常。
提醒:當被監控的某個Redis服務器出現問題時,哨兵可以通過API給程序員發送通知
自動故障轉移:主服務器宕機,哨兵會開始一次自動故障轉移操作,升級一個從服務器為主服務器,並讓其他從服務器改為複製新的主服務器.
配置 Sentinel
Redis 源碼中包含了一個名為 sentinel.conf 的文件, 這個文件是一個帶有詳細註釋的 Sentinel 配置文件示例。
運行一個 Sentinel 所需的最少配置如下所示:
1)sentinel monitor mymaster 192.168.10.202 6379 2
Sentine監聽的maste地址,第一個參數是給master起的名字,第二個參數為master IP,第三個為master端口,第四個為當該master掛了的時候,若想將該master判為失效,
在Sentine集群中必須至少2個Sentine同意才行,只要該數量不達標,則就不會發生故障遷移。
-----------------------------------------------------------------------------------------------
2)sentinel down-after-milliseconds mymaster 30000
表示master被當前sentinel實例認定為失效的間隔時間,在這段時間內一直沒有給Sentine返回有效信息,則認定該master主觀下線。
只有在足夠數量的 Sentinel 都將一個服務器標記為主觀下線之後, 服務器才會被標記為客觀下線,將服務器標記為客觀下線所需的 Sentinel 數量由對主服務器的配置決定。
-----------------------------------------------------------------------------------------------
3)sentinel parallel-syncs mymaster 2
當在執行故障轉移時,設置幾個slave同時進行切換master,該值越大,則可能就有越多的slave在切換master時不可用,可以將該值設置為1,即一個一個來,這樣在某個
slave進行切換master同步數據時,其餘的slave還能正常工作,以此保證每次只有一個從服務器處於不能處理命令請求的狀態。
-----------------------------------------------------------------------------------------------
4)sentinel can-failover mymaster yes
在sentinel檢測到O_DOWN後,是否對這臺redis啟動failover機制
-----------------------------------------------------------------------------------------------
5)sentinel auth-pass mymaster 20180408
設置sentinel連接的master和slave的密碼,這個需要和redis.conf文件中設置的密碼一樣
-----------------------------------------------------------------------------------------------
6)sentinel failover-timeout mymaster 180000
failover過期時間,當failover開始後,在此時間內仍然沒有觸發任何failover操作,當前sentinel將會認為此次failoer失敗。
執行故障遷移超時時間,即在指定時間內沒有大多數的sentinel 反饋master下線,該故障遷移計劃則失效
-----------------------------------------------------------------------------------------------
7)sentinel config-epoch mymaster 0
選項指定了在執行故障轉移時, 最多可以有多少個從服務器同時對新的主服務器進行同步。這個數字越小, 完成故障轉移所需的時間就越長。
-----------------------------------------------------------------------------------------------
8)sentinel notification-script mymaster /var/redis/notify.sh
當failover時,可以指定一個"通知"腳本用來告知當前集群的情況。
腳本被允許執行的最大時間為60秒,如果超時,腳本將會被終止(KILL)
-----------------------------------------------------------------------------------------------
9)sentinel leader-epoch mymaster 0
同時一時間最多0個slave可同時更新配置,建議數字不要太大,以免影響正常對外提供服務。
主觀下線和客觀下線
主觀下線:指的是單個 Sentinel 實例對服務器做出的下線判斷。客觀下線:指的是多個 Sentinel 實例在對同一個服務器做出 SDOWN主觀下線 判斷。
Redis Sentinel的工作原理
1.每個 Sentinel 以每秒一次的頻率向它所知的主服務器、從服務器以及其他 Sentinel 實例發送一個 PING 命令。
2.如果一個實例距離最後一次有效回覆 PING 命令的時間超過指定的值, 那麼這個實例會被 Sentinel 標記為主觀下線。
3.正在監視這個主服務器的所有 Sentinel 要以每秒一次的頻率確認主服務器的確進入了主觀下線狀態。
4.有足夠數量的 Sentinel 在指定的時間範圍內同意這一判斷, 那麼這個主服務器被標記為客觀下線。
5.每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有主服務器和從服務器發送 INFO 命令。 當一個主服務器被 Sentinel 標記為客觀下線時, Sentinel 向下線主服務器的所有從服務器發送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
6.Sentinel 和其他 Sentinel 協商 主節點 的狀態,如果 主節點 處於 SDOWN 狀態,則投票自動選出新的 主節點。將剩餘的 從節點 指向 新的主節點 進行 數據複製。
7.當沒有足夠數量的 Sentinel 同意 主服務器 下線時, 主服務器 的 客觀下線狀態 就會被移除。當 主服務器 重新向 Sentinel 的 PING 命令返回 有效回覆 時,主服務器 的 主觀下線狀態 就會被移除。
自動發現 Sentinel 和從服務器
一個 Sentinel 可以與其他多個 Sentinel 進行連接, 各個 Sentinel 之間可以互相檢查對方的可用性, 並進行信息交換。
你無須為運行的每個 Sentinel 分別設置其他 Sentinel 的地址, 因為 Sentinel 可以通過發佈與訂閱功能來自動發現正在監視相同主服務器的其他 Sentinel。
每個 Sentinel 會以每兩秒一次的頻率, 通過發佈與訂閱功能, 向被它監視的所有主服務器和從服務器的頻道發送一條信息, 信息中包含了 Sentinel 的 IP 地址、端口號和運行 ID (runid)。每個 Sentinel 都訂閱了被它監視的所有主服務器和從服務器的頻道, 查找之前未出現過的 sentinel 。 當一個 Sentinel 發現一個新的 Sentinel 時, 它會將新的 Sentinel 添加到一個列表中。Sentinel 發送的信息中還包括完整的主服務器當前配置。 如果一個 Sentinel 包含的主服務器配置比另一個 Sentinel 發送的配置要舊, 那麼這個 Sentinel 會立即升級到新配置上。在將一個新 Sentinel 添加到監視主服務器的列表上面之前, Sentinel 會先檢查列表中是否已經包含了和要添加的 Sentinel 擁有相同運行 ID 或者相同地址(包括 IP 地址和端口號)的 Sentinel , 如果是的話, Sentinel 會先移除列表中已有的那些擁有相同運行 ID 或者相同地址的 Sentinel , 然後再添加新 Sentinel
故障轉移
一次故障轉移操作由以下步驟組成:
發現主服務器已經進入客觀下線狀態。對我們的當前紀元進行自增, 並嘗試在這個紀元中當選。如果當選失敗, 那麼在設定的故障遷移超時時間的兩倍之後, 重新嘗試當選。 如果當選成功, 那麼執行以下步驟。選出一個從服務器,並將它升級為主服務器。向被選中的從服務器發送 SLAVEOF NO ONE 命令,讓它轉變為主服務器。通過發佈與訂閱功能, 將更新後的配置傳播給所有其他 Sentinel , 其他 Sentinel 對它們自己的配置進行更新。向已下線主服務器的從服務器發送 SLAVEOF 命令, 讓它們去複製新的主服務器。當所有從服務器都已經開始複製新的主服務器時, 領頭 Sentinel 終止這次故障遷移操作。
閱讀更多 Java架構胖胖 的文章