Redis詳解(六)——哨兵機制

来源:https://www.cnblogs.com/lee0527/archive/2020/02/03/12256870.html
-Advertisement-
Play Games

Redis詳解(六)——哨兵機制 一、概述 Redis Sentinel是一個分散式系統,為Redis提供高可用性解決方案。可以在一個架構中運行多個 Sentinel 進程(progress), 這些進程使用流言協議(gossip protocols)來 接收關於主伺服器是否下線的信息, 並使用投票 ...


Redis詳解(六)——哨兵機制

一、概述

Redis Sentinel是一個分散式系統,為Redis提供高可用性解決方案。可以在一個架構中運行多個 Sentinel 進程(progress), 這些進程使用流言協議(gossip protocols)來 接收關於主伺服器是否下線的信息, 並使用投票協議(agreement protocols)來決定是否執行自動故 障遷移, 以及選擇哪個從伺服器作為新的主伺服器。

Redis 的 Sentinel 系統用於管理多個 Redis 伺服器(instance) 該系統執行以下三個任務:

  • 監控(Monitoring): Sentinel 會不斷地定期檢查你的主伺服器和從伺服器是否運作正常。
  • 提醒(Notification): 當被監控的某個 Redis 伺服器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程式發送通知。
  • 自動故障遷移(Automaticfailover): 當一個主伺服器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主伺服器的其中 一個從伺服器升級為新的主伺服器, 並讓失效主伺服器的其他從伺服器改為複製新的主伺服器; 當客 戶端試圖連接失效的主伺服器時, 集群也會向客戶端返回新主伺服器的地址, 使得集群可以使用新主 伺服器代替失效伺服器。

二、Sentinel 工作原理分析

(1)哨兵文件詳解

配置一:sentinel monitor <master-name> <ip> <port> <quorum>

這個配置表達的是 哨兵節點定期監控 名字叫做 <master-name> 並且 IP 為 <ip> 埠號為 <port> 的主節點。<quorum> 表示的是哨兵判斷主節點是否發生故障的票數。也就是說如果我們將<quorum>設置為2就代表至少要有兩個哨兵認為主節點故障了,才算這個主節點是客觀下線的了,一般是設置為sentinel節點數的一半加一。

配置二:sentinel down-after-milliseconds <master-name> <times>

每個哨兵節點會定期發送ping命令來判斷Redis節點和其餘的哨兵節點是否是可達的,如果超過了配置的<times>時間沒有收到pong回覆,就主觀判斷節點是不可達的,<times>的單位為毫秒。

配置三:sentinel parallel-syncs <master-name> <nums>

當哨兵節點都認為主節點故障時,哨兵投票選出的leader會進行故障轉移,選出新的主節點,原來的從節點們會向新的主節點發起複制,這個配置就是控制在故障轉移之後,每次可以向新的主節點發起複制的節點的個數,最多為<nums>個,因為如果不加控制會對主節點的網路和磁碟IO資源很大的開銷。

配置四:sentinel failover-timeout <master-name> <times>

這個代表哨兵進行故障轉移時如果超過了配置的<times>時間就表示故障轉移超時失敗。

配置五: sentinel auth-pass <master-name> <password>

如果主節點設置了密碼,則需要這個配置,否則哨兵無法對主節點進行監控。

(2)為什麼要用到哨兵

哨兵(Sentinel)主要是為瞭解決在主從複製架構中出現宕機的情況,主要分為兩種情況:

1).從Redis宕機

這個相對而言比較簡單,在Redis中從庫重新啟動後會自動加入到主從架構中,自動完成同步數據。在Redis2.8版本後,主從斷線後恢復的情況下實現增量複製。

2).主Redis宕機

這個相對而言就會複雜一些,需要以下2步才能完成

a. 在從資料庫中執行SLAVEOF NO ONE命令,斷開主從關係並且提升為主庫繼續服務

b. 第二步,將主庫重新啟動後,執行SLAVEOF命令,將其設置為其他庫的從庫,這時數據就能更新回來

由於這個手動完成恢復的過程其實是比較麻煩的並且容易出錯,所以Redis提供的哨兵(sentinel)的功能來解決

(3)哨兵機制(sentinel)的高可用

Sentinel(哨兵)是Redis 的高可用性解決方案:由一個或多個Sentinel 實例 組成的Sentinel 系統可以監視任意多個主伺服器,以及這些主伺服器屬下的所有從伺服器,併在被監視的主伺服器進入下線狀態時,自動將下線主伺服器屬下的某個從伺服器升級為新的主伺服器。

如圖所示

img

在Server1 掉線後:

img

升級Server2 為新的主伺服器:

img

(4)哨兵的定時監控

任務1:每個哨兵節點每10秒會向主節點和從節點發送info命令獲取最拓撲結構圖,哨兵配置時只要配置對主節點的監控即可,通過向主節點發送info,獲取從節點的信息,並當有新的從節點加入時可以馬上感知到

img

任務2:每個哨兵節點每隔2秒會向redis數據節點的指定頻道上發送該哨兵節點對於主節點的判斷以及當前哨兵節點的信息,同時每個哨兵節點也會訂閱該頻道,來瞭解其它哨兵節點的信息及對主節點的判斷,其實就是通過消息publish和subscribe來完成的

img

任務3:每隔1秒每個哨兵會向主節點、從節點及其餘哨兵節點發送一次ping命令做一次心跳檢測,這個也是哨兵用來判斷節點是否正常的重要依據

img

主觀下線:所謂主觀下線,就是單個sentinel認為某個服務下線(有可能是接收不到訂閱,之間的網路不通等等原因)。

sentinel會以每秒一次的頻率向所有與其建立了命令連接的實例(master,從服務,其他sentinel)發ping命令,通過判斷ping回覆是有效回覆,還是無效回覆來判斷實例時候線上(對該sentinel來說是“主觀線上”)。

sentinel配置文件中的down-after-milliseconds設置了判斷主觀下線的時間長度,如果實例在down-after-milliseconds毫秒內,返回的都是無效回覆,那麼sentinel回認為該實例已(主觀)下線,修改其flags狀態為SRI_S_DOWN。如果多個sentinel監視一個服務,有可能存在多個sentinel的down-after-milliseconds配置不同,這個在實際生產中要註意。

客觀下線:當主觀下線的節點是主節點時,此時該哨兵3節點會通過指令sentinel is-masterdown-by-addr尋求其它哨兵節點對主節點的判斷,如果其他的哨兵也認為主節點主觀線下了,則當認為主觀下線的票數超過了quorum(選舉)個數,此時哨兵節點則認為該主節點確實有問題,這樣就客觀下線了,大部分哨兵節點都同意下線操作,也就說是客觀下線

img

(5)哨兵lerder選舉流程

如果主節點被判定為客觀下線之後,就要選取一個哨兵節點來完成後面的故障轉移工作,選舉出一個leader的流程如下:

a)每個線上的哨兵節點都可以成為領導者,當它確認(比如哨兵3)主節點下線時,會向其它哨兵發is-master-down-by-addr命令,征求判斷並要求將自己設置為領導者,由領導者處理故障轉移;
b)當其它哨兵收到此命令時,可以同意或者拒絕它成為領導者;
c)如果哨兵3發現自己在選舉的票數大於等於num(sentinels)/2+1時,將成為領導者,如果沒有超過,繼續選舉…………

img

(6)自動故障轉移機制

在從節點中選擇新的主節點

sentinel狀態數據結構中保存了主服務的所有從服務信息,領頭sentinel按照如下的規則從從服務列表中挑選出新的主服務

  1. 過濾掉主觀下線的節點
  2. 選擇slave-priority最高的節點,如果由則返回沒有就繼續選擇
  3. 選擇出複製偏移量最大的系節點,因為複製便宜量越大則數據複製的越完整,如果由就返回了,沒有就繼續
  4. 選擇run_id最小的節點

img

更新主從狀態

通過slaveof no one命令,讓選出來的從節點成為主節點;並通過slaveof命令讓其他節點成為其從節點。

將已下線的主節點設置成新的主節點的從節點,當其回覆正常時,複製新的主節點,變成新的主節點的從節點

同理,當已下線的服務重新上線時,sentinel會向其發送slaveof命令,讓其成為新主的從

三、Sentinel獲取伺服器信息

(1) Sentinel獲取主伺服器信息

    Sentinel預設會以每10秒一次的頻率,通過命令連接向主伺服器發送info命令,通過分析info命令的回覆來獲取主伺服器的當前信息,就像在上篇講到的複製功能,在客戶端輸入info replication 命令一樣,Sentinel可以獲取以下兩方面的信息:

    (1) 關於主伺服器本身的信息,包括伺服器run_id,role的伺服器角色。

    (2) 關於所有從伺服器的信息,每個從伺服器都由一個slave字元串開頭的行記錄,記錄了從伺服器IP和埠(主伺服器中有從庫的配置信息)。

(2)Sentinel獲取從伺服器信息

    當Sentinel發現主伺服器有新的從伺服器出現時,Sentinel除了會為這個新的從伺服器創建相應的實例結構(sentinelRedisInstance)之外,Sentinel還會創建連接到從伺服器的命令連接和訂閱連接。Sentinel預設會以每10秒一次的頻率通過命令連接從伺服器發送info命令,通過分析info命令的回覆來獲取從伺服器的當前信息。包括:從伺服器運行run_ID、從伺服器角色role、主伺服器的ip及埠、主從伺服器的連接狀態master_link_status、從伺服器的優先順序slave_priority。

(3)Sentinel向主從伺服器發送信息

    在預設情況下, Sentinel會以每2秒一次的頻率,通過命令連接向所有被監視的主伺服器和從伺服器發送以下格式的命令:

  img

    這條命令向伺服器的_sentinel_:hello頻道發送了一條信息,信息的內容由多個參數組成:

    (1) 以s_開頭以參數記錄的是sentinel本身的信息。

    (2) 而m_開頭的參數記錄的則是主伺服器的信息,如果sentinel正在監視的是主伺服器,那麼這些參數就是主伺服器的信息,如果sentinel正在監視的是從伺服器,那麼這些參數記錄就是從伺服器正在複製的主伺服器的信息。

參數 描述
S_ip Sentinel的ip地址
S_port Sentinel的埠號
S_runid Sentinel的運行ID
S_epoch Sentinel 的當前配置紀元
m_name 主伺服器的名字
M_ip 主伺服器的IP地址
M_port 主伺服器的埠號
M_epoch 主伺服器的當前配置紀元

    

以下是一條sentinel通過publish命令向主伺服器發送的信息示例:

  img

這個示例中sentinel的ip地址為172.0.0.1埠號為26379, 運行ID為後面一串,當前紀元為0。主伺服器的名字為mymaster,ip地址為127.0.0.1,埠號為6379, 當前紀元為0。

(4)sentinel接收來自主伺服器和從伺服器的頻道信息

    當sentinel與一個主伺服器或者從伺服器建立起訂閱連接之後,Sentinel就會通過訂閱連接,向伺服器發送以下命令:subscribe_sentinel_:hello 。對於每個與Sentinel連接的伺服器,Sentinel既通過命令連向伺服器的_sentinel_:hello頻道發送信息,又通過訂閱連接從伺服器的_sentinel_:hello頻道接收信息。

    當有三個sentinel,分別是sentinel1、sentinel2 、sentinel3。三個sentinel在監視同一個伺服器,那麼當sentinel1向伺服器的_sentinel_:hello頻道發送一條信息時,所有訂閱了_sentinel_:hello頻道的sentinel(包括sentinel1自己在內)都會收到這條信息。

    當一個sentinel從_sentinel_:hello頻道收到一條信息時,sentinel會對這條信息進行分析,提取出信息中sentinel 的 ip 、port、runID等8個參數,併進行以下檢查:

    (1) 如果信息中記錄的sentinel運行ID和接收信息的sentinel運行ID相同,那麼說明這條信息是sentinel自己發送的,sentinel將丟棄這條信息,不做進一步處理。

    (2) 相反地,如果信息中記錄的sentinel運行ID和接收信息的sentinel運行ID不相同,那說明這條信息監視同一個伺服器的其它sentinel發來的,接收信息的sentinel將根據信息中的參數,對相應主伺服器的實例結構進行更新。

(5)sentinel更新自己的sentinels字典

    sentinel為主伺服器創建實例結構中的sentinels字典,保存了sentinel本身,還監視這個主伺服器的其他sentinel的資料。當一個sentinel接收到其他sentinels發來的信息時,接收的sentinel會從信息中分析並提取出兩方面參數:

    (1)與sentinel有關的參數,包括sentinel的ip、port、runid、配置紀元。

    (2)與主伺服器有關的參數, 包括監視主伺服器的ip、port、runid、配置紀元。

    假設分別有三個sentinel: 127.0.0.1:26379、127.0.0.1:26380、127.0.0.1:26381。三個sentinel正在監視主伺服器127.0.0.1:6379, 那麼當127.0.0.1:26379這個sentinel接收到以下消息時:

    img

    這個sentinel將執行以下動作:

    (1) 第一條信息發送者為自己,信息忽略。

    (2) 第二條信息發送者為26381, sentinel會根據信息提取出內容,對sentinels字典中26381對應的實例結構進行更新。

    (3) 第三條信息發送者為23680,同樣更新字典中的23680對應的實例結構。

    每個sentinel都有自己的一個sentinels字典, 對於26379的sentinel它的sentinels字典信息保存了26380和26381兩個sentinel信息。其它sentinel也一樣。

(6)sentinel創建連向其他sentinel的命令連接

    當sentinel通過頻道信息發現一個新的sentinel時,不僅更新sentinels字典,還會創建一個連向sentinel命令連接,而新的sentinel也會創建連向這個sentinel的命令連接,最終監視同一個主伺服器的多個sentinel將形成相互連接的網路。如下圖所示:

img

四、Sentinel的工作原理總結

1):每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他 Sentinel 實例發送一個 PING 命令。

2):如果一個實例(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被 Sentinel 標記為主觀下線。

3):如果一個Master被標記為主觀下線,則正在監視這個Master的所有 Sentinel 要以每秒一次的頻率確認Master的確進入了主觀下線狀態。

4):當有足夠數量的 Sentinel(大於等於配置文件指定的值)在指定的時間範圍內確認Master的確進入了主觀下線狀態, 則Master會被標記為客觀下線 。

5):在一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有Master,Slave發送 INFO 命令 。

6):當Master被 Sentinel 標記為客觀下線時,Sentinel 向下線的 Master 的所有 Slave 發送 INFO 命令的頻率會從 10 秒一次改為每秒一次 。

7):若沒有足夠數量的 Sentinel 同意 Master 已經下線, Master 的客觀下線狀態就會被移除。

若 Master 重新向 Sentinel 的 PING 命令返回有效回覆, Master 的主觀下線狀態就會被移除。

五、參考資料

https://www.cnblogs.com/Eugene-Jin/p/10819601.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原理 項目的資料庫字典表是一個很重要的文檔。通過此文檔可以清晰的瞭解數據表結構及開發者的設計意圖。 通常為了方便我都是直接在資料庫中建表,然後通過工具導出數據字典。 在Mysql資料庫中有一個information_schema庫,它提供了訪問資料庫元數據的方式。 什麼是元數據呢?就是關於數據的數據 ...
  • Redis詳解(八)——企業級解決方案 緩存預熱 緩存預熱就是系統上線後,提前將相關的緩存數據直接載入到緩存系統。避免在用戶請求的時候,先查詢資料庫,然後再將數據緩存的問題!用戶直接查詢事先被預熱的緩存數據! 緩存預熱解決方案: 緩存雪崩 緩存雪崩就是在一個較短的時間內,緩存中較多的key集中過期 ...
  • python和其他語言一樣,也有大量的第三方庫 在安裝python時預設都會安裝pip,安裝了pip後 在cmd.exe下可以運行pip 安裝庫 pip install 庫的名字 換源 因為PyPi地址在國外,國內訪問速度慢有些地方甚至訪問不了,把鏡像源換為國內地址速度簡直飛起 國內一些常用的軟體源 ...
  • Standard Template Library(STL)主要由兩種組件構成1:一是容器(container),包括vector、list、set、map等;另一種組件是用以操作這些容器的所謂泛型演算法(generic algorithm),包括find()、sort()、replace()、mer... ...
  • Redis詳解(七)——集群 ​Redis3.0版本之前,可以通過Redis Sentinel(哨兵)來實現高可用 ( HA ),從3.0版本之後,官方推出了Redis Cluster,它的主要用途是實現數據分片(Data Sharding),不過同樣可以實現HA,是官方當前推薦的方案。 在Redi ...
  • 可以說string和vector是C++標準庫中最重要的兩種類型,string支持可變長字元串,而vector表示可變長的集合。 string 頭文件:<string> 定義在命名空間 std 中,using std::string; string s1; // 預設初始化,s1是一個空串 stri ...
  • 網路原理是工程師的必須瞭解的電腦基礎知識,先推薦下兩本好書,《圖解HTTP》和《圖解TCP/IP》。 《圖解TCP/IP》講解網路基礎知識、TCP/IP基礎知識、數據鏈路、IP協議、IP協議相關技術、TCP與UDP、路由協議、應用協議、網路安全等內容,《圖解HTTP》對HTTP協議進行了全面系統的 ...
  • 時間序列資料庫(TSDB)初識與選擇 本文作者由 MageByte 團隊的 「借來方向」編寫,關註公眾號 給你更多硬核技術 背景 這兩年互聯網行業掀著一股新風,總是聽著各種高大上的新名詞。大數據、人工智慧、物聯網、機器學習、商業智能、智能預警啊等等。 以前的系統,做數據可視化,信息管理,流程式控制制。現 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...