天天看點

Redis哨兵原理總結(二)

目錄

二、哨兵是如何解決“問題一”的?

2.1 、主從模式哨兵部署

2.2、三個定時監控任務 

2.3、主觀下線與客觀下線

2.4、上司者哨兵節點選舉

2.5、故障轉移

本博文主要總結關于哨兵的一些理論知識,主要關注點有一下幾個方面:

一、哨兵解決了什麼問題?

二、哨兵是如何解決“問題一”的?

三、如何使用哨兵?

四、Redis Sentinel用戶端實作的原理是什麼?Java如何操作Redis Sentinel?

二、哨兵是如何解決“問題一”的?

這個就要從哨兵的原理說起了。下面主要從三個定時監控任務、主/客觀下線、上司者Sentinel節點選舉、故障轉移這四個方面總結。

2.1 、主從模式哨兵部署

(1)哨兵節點的數量盡量為大于等于3的奇數,提高對故障判斷的準确性。

(2)哨兵節點不應該部署在一台實體機器上。

(3)哨兵節點集合可以隻監控一個主節點,也可以監控多個主節點。

下圖可發現:哨兵不僅監控着主節點和從節點,還監控着其他哨兵節點。

Redis哨兵原理總結(二)

2.2、三個定時監控任務 

第一個任務:擷取最新的主從拓撲結構

每隔10秒,每個哨兵會向master節點和slave節點發送info指令,擷取最新的主從拓撲結構。

第二個任務:發現新的哨兵節點、哨兵節點之間交換這節點的狀态

每隔2秒,每隔哨兵會向master節點的_sentinel_:hello頻道上發送該哨兵節點對master節點的判斷,以及目前sentinel節點的資訊。因為,每個哨兵節點都訂閱了master節點的_sentinel_:hello頻道,其他哨兵節點就可以了解其他哨兵節點的資訊,以及其他哨兵節點對主節點的判斷。

第三個任務:判斷master節點、slave節點、其他哨兵節點是否線上

每隔1秒,每個哨兵節點會向master節點、slave節點、其他哨兵節點發送一條ping指令,做心跳檢測,來确認這些節點是否可達。

2.3、主觀下線與客觀下線

2.3.1、主觀下線

在第三個定時任務寫道,每個哨兵節點會對matser節點、slave節點、其他哨兵節點定時發送ping指令,當這些節點超過sentinel.conf檔案配置的down-after-milliseconds時,該哨兵就會做出失敗的判定,此為主觀下線。即自己ping不通了就判定是下線了,可能會存在誤判。是以,才有了客觀下線,多數人判定下線了才是真的下線。

在哨兵執行個體上有這樣一個配置檔案,即sentinel.conf檔案,其中down-after-milliseconds就是心跳檢測的逾時時間:

#13秒逾時
sentinel down-after-milliseconds pmaster 13000
           

2.3.2、客觀下線

當一個哨兵節點A發現下線的是master節點,就會向其他哨兵節點發送一個sentinel is-master-down-by-addr指令,詢問其他節點對該addr主節點的狀态判斷,當超過sentinel.conf配置的quorum個數。此時,哨兵節點A就會對該master節點做出客觀下線的決定了。

在哨兵執行個體上有這樣一個配置檔案,即sentinel.conf檔案,下面就是代表該哨兵監控的是master的名字是pmaster,ip位址是127.0.0.1,端口号是6379,最後的2就是:代表要判斷主節點最終不可達(主節點下線)所需要的票數。

sentinel monitor pmaster 127.0.0.1 6379 2
           

注意:當從節點、哨兵節點主觀下線後,沒有後續的故障轉移操作。

2.3.3、介紹sentinel is-master-down-by-addr指令的使用方法

sentinel is-master-down-by-addr <ip> <port> <current_epoch> <ruuid>
           

ip:主節點的ip位址

port:主節點的端口号

current_epoch:目前哨兵配置的紀元

runid:此參數有兩種類型,不同類型決定了此API作用不同。

           當runid等于 * 時,作用是哨兵節點直接交換對主節點下線的決定;

           當runid等于目前哨兵節點的runid時,作用是目前哨兵節點希望目标哨兵節點同意自己成為leader的請求,這裡就與下一節的上司者選舉有關了。

例如,當一個哨兵節點向其他哨兵節點發送一下指令

sentinel is-master-down-by-addr 127.0.0.1 6379 0 *
           

收到其他哨兵的傳回結果包括是三個參數:

down_state:目标哨兵節點對于主節點的主觀下線判斷,1代表下線,0代表線上。

leader_runid:等于 * 時,代表傳回結果隻是用來判斷主節點是否下線;當等于具體的runid,代表目标哨兵同意runid的哨兵成為負責故障轉移工作的上司者。

2.4、上司者哨兵節點選舉

到此為止,已經客觀判斷了主節點下線了,是不是立刻就執行故障轉移了呢?不是,現在還需要選舉一個哨兵作為上司者,來專門負責故障轉移的工作。

Redis選舉上司者的算法是Raft算法,該算法不在這裡介紹。該算法可參考GitHub首頁:https://raft.github.io/

選舉上司者的大緻思路:

(1)首先,每個線上的哨兵節點都有資格成為了上司者。當某一個哨兵節點A主觀判斷主節點下線時,就會向其他哨兵節點發送sentinel is-master-down-by-addr指令,并請求将自己設定為上司者。這裡,就需要将runid設定為自己的runid。

(2)收到指令的哨兵節點,如果沒有同意過其他哨兵節點的sentinel is-master-down-by-addr指令,就會同意該請求,否則拒絕。因為,每個哨兵隻有這麼一張票,投了别人,就再沒有投其他哨兵的機會了。

(3)如果哨兵節點A發現自己的票數已經大于或等于max(quorum, num(sentinels)/2+1),哨兵節點A就成為了上司者。

(4)如果此過程沒有選舉出上司者,将進行下一次選舉。

一般,選舉過程非常快,誰先完成客觀下線判斷,誰就是上司者。

2.5、故障轉移

到此,我們選擇出了上司者,來負責故障轉移。具體轉移步驟如下:

(1)在從節點選出一個節點作為新的主節點。

        (a)過濾掉“不健康”(主觀下線、斷線)、5秒内沒有回複過哨兵節點的ping指令、與主節點失聯超過down-after-milliseconds*10秒的從節點。

        (b)選擇slave-priority最高的從節點清單。如果存在則傳回,否則繼續下一步。slave-priority代表從節點的優先級,它是在sentinel.conf檔案設定的,其數值越小,優先級越高。但是為0,永遠不會被選擇為主節點的。

        (c)選擇複制偏移量最大的從節點(複制的最完整),如果存在則傳回,否則繼續。

        (d)選擇runid最小的從節點。

(2)上司者會對(1)選出來的新節點做slaveof no one指令,讓其成為主節點。

(3)上司者向剩餘的從節點發送指令,讓它們成為新主節點的從節點,這裡的複制規則就與sentinel.conf檔案在的參數parallel-syncs有關。

(4)哨兵節點集合将原來的主節點更新為從節點,并保持對其關注,當其恢複後指令它去複制新的主節點。

 在第(1)步中選出最好的從節點流程圖:

Redis哨兵原理總結(二)

關于其他Redis Sentinel機制與用法:

1、 Redis Sentinel機制與用法

2、Redis-哨兵模式和高可用叢集解析

下一篇:Redis哨兵原理總結(三)将介紹哨兵部署、Redis節點的conf檔案和哨兵節點的conf檔案解釋、哨兵日志解釋