想進大廠拿高薪?掌握Redis的Sentinel哨兵原理將是至關(guān)重要的突破口

  • 集群監(jiān)控

監(jiān)控Redis master和slave進程的正常工作

  • 消息通知

如果某個Redis實例有故障,那么哨兵負(fù)責(zé)發(fā)送報警消息給管理員

  • 故障轉(zhuǎn)移

若master node宕機,會自動轉(zhuǎn)移到slave node上

  • 配置中心

若發(fā)生故障轉(zhuǎn)移,通知client客戶端新的master地址

哨兵本身也是分布式,作為一個集群運行:

  • 故障轉(zhuǎn)移時,判斷一個master node是否宕機,需要大部分哨兵都同意,涉及分布式選舉
  • 即使部分哨兵節(jié)點宕機,哨兵集群還是能正常工作

目前采用的是sentinal 2版本,sentinal 2相對于sentinal 1來說,重寫了很多代碼,主要是讓故障轉(zhuǎn)移的機制和算法變得更加健壯和簡單

哨兵 + Redis主從的部署架構(gòu)不保證數(shù)據(jù)零丟失,只保證redis集群的高可用性。

1.1 為何2個節(jié)點無法正常工作?

必須部署2個以上的節(jié)點。若僅部署2個實例,quorum=1

+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+

Configuration: quorum = 1

master宕機,s1和s2中只要有1個哨兵認(rèn)為master宕機就可以進行切換,同時會在s1和s2中選舉出一個執(zhí)行故障轉(zhuǎn)移. 但此時,需要majority,也就是大多數(shù)哨兵都是運行的,2個哨兵的majority就是2

2個哨兵的majority=2 3個哨兵的majority=2 4個哨兵的majority=2 5個哨兵的majority=3

2個哨兵都運行著,就可以允許執(zhí)行故障轉(zhuǎn)移

若整個M1和S1運行的機器宕機了,那么哨兵僅剩1個,此時就無majority來允許執(zhí)行故障轉(zhuǎn)移,雖然另外一臺機器還有一個R1,但故障轉(zhuǎn)移不會執(zhí)行

1.2 3節(jié)點哨兵集群

+----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+

Configuration: quorum = 2,majority

若M1節(jié)點宕機了,還剩下2個哨兵,S2和S3可以一致認(rèn)為master宕機了,然后選舉出一個來執(zhí)行故障轉(zhuǎn)移

同時3個哨兵的majority是2,所以余存的2個哨兵運行著,就可執(zhí)行故障轉(zhuǎn)移

02 Redis Sentinel 架構(gòu)

2.1 Redis Sentinel故障轉(zhuǎn)移

  1. 多個sentinel發(fā)現(xiàn)并確認(rèn)master有問題。
  2. 選舉出一個sentinel作為領(lǐng)導(dǎo)。
  3. 選出一個slave作為master.
  4. 通知其余slave成為新的master的slave.
  5. 通知客戶端主從變化
  6. 等待老的master復(fù)活成為新master的slave
  • 可監(jiān)控多套

03 安裝與配置

  1. 配置開啟主從節(jié)點
  2. 配置開啟sentinel監(jiān)控主節(jié)點。(sentinel是特殊的redis)
  3. 實際應(yīng)該多機器
  4. 詳細(xì)配置節(jié)點

Redis 主節(jié)點

[啟動]
redis-server redis- 7000.conf

[配置]
port 7000
daemonize yes
pidfile /var/run/redis-7000.pid
logfile "7000.log"
dir "/opt/soft/redis/data/"

Redis 從節(jié)點

[啟動]
redis-server redis-7001.conf
redis-server redis-7002.conf

slave-1[配置]

port 7001
daemonize yes
pidfile /var/run/redis-7001.pid
logfile "7001.log"
dir "/opt/soft/redis/data/"
slaveof 127.0.0.1 7000

slave-2[配置]
port 7002
daemonize yes
pidfile /var/run/redis-7002.pid
logfile "7002.log"
dir "/opt/soft/redis/data/"
slaveof 127.0.0.1 7000

Sentinel 主要配置

port $(port)
dir "/opt/soft/redis/data/"
logfile " $(port).log"
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

3.1 演示

  • 主節(jié)點配置
  • 重定向
  • 打印檢查配置文件
  • 啟動

04 客戶端

  • 客戶端實現(xiàn)基本原理-1
  • 客戶端實現(xiàn)基本原理-2
  • 客戶端實現(xiàn)基本原理-3 驗證
  • 客戶端實現(xiàn)基本原理-4 通知(發(fā)布訂閱))

4.1 客戶端接入流程

  1. Sentinel地址集合
  2. masterName
  3. 不是代理模式
JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName, sentinelSet, poolConfig, timeout);

Jedis jedis = null;
try {
    jedis = redisSentinelPool.getResource();
    //jedis command
} catch (Exception e) {
    logger.error(e.getMessage(), e);
} finally {
    if (jedis != null)
        jedis.close();
}

05 定時任務(wù)

  1. 每10s 每個 sentinel 對 master 和 replica 執(zhí)行 INFO 命令
  • 發(fā)現(xiàn) replica 節(jié)點
  • 確認(rèn)主從關(guān)系
  1. 每 2s 每個 sentinel 通過 master 節(jié)點的channel交換信息(pub/sub)
  • 通過 sentinel :java頻道交互
  • 交互對節(jié)點的"看法”和自身信息
  1. 每 1s 每個 sentinel 對其他 sentinel 和 redis 執(zhí)行ping
  • 心跳檢測,失敗判定依據(jù)

06 主觀下線和客觀下線

6.1 主觀下線(Subjectively Down,SDOWN)

單個 Sentinel 節(jié)點對服務(wù)器做出的下線判斷,即單個 Sentinel 認(rèn)為某個服務(wù)下線(有可能是接收不到訂閱,之間的網(wǎng)絡(luò)不通等一系列原因)。

注意主觀下線是每個sentinel節(jié)點對Redis節(jié)點失敗的"偏見”。所以還需要客觀下線機制。

6.2 客觀下線(Objectively Down,ODOWN)

多個 Sentinel 實例在對同一個服務(wù)器做出 SDOWN 判斷,并且通過命令互相交流之后,得出的服務(wù)器下線判斷,然后開啟 failover。

只有在足夠數(shù)量( 超過quorum個)的 Sentinel 都將一個服務(wù)器標(biāo)記為主觀下線之后, 服務(wù)器才會被標(biāo)記為客觀下線(ODOWN)。只有當(dāng) Master 被認(rèn)定為客觀下線時,才會發(fā)生故障遷移。

6.3 仲裁

仲裁指配置文件中的 quorum 參數(shù)。某個 Sentinel 先將 Master 節(jié)點標(biāo)記為主觀下線,然后會將這個判定通過 sentinel is-master-down-by-addr 命令詢問其他 Sentinel 節(jié)點是否也同樣認(rèn)為該 addr 的 Master 節(jié)點要做主觀下線。

sentinel monitor <masterName> <ip> < port> <quorum>
sentinel monitor myMaster 127.0.0.1 6379 2
# 
sentinel down-after-milliseconds < masterName> < timeout>
sentinel down-after-milliseconds mymaster 30000

最后當(dāng)達成這一共識的 Sentinel 個數(shù)達到前面說的 quorum 設(shè)置的值時,該 Master 節(jié)點會被認(rèn)定為客觀下線并進行故障轉(zhuǎn)移。 quorum 值一般設(shè)為 Sentinel 個數(shù)的二分之一加 1,例如 3 個 Sentinel 就設(shè)為 2。

綜上可得

6.4 哨兵工作原理

  1. 每個 Sentinel 以 1次/s 向他所知的 Master,Slave 以及其他 Sentinel 節(jié)點發(fā)送一個 PING
  2. 若一個實例距離最后一次有效回復(fù) PING 的時間超過配置文件 down-after-milliseconds,則該實例會被 Sentinel 標(biāo)記為 主觀下線
  3. 若一個 Master 被標(biāo)記為主觀下線,則正在監(jiān)視該 Master 的所有 Sentinel 會 1次/s 確認(rèn) Master 是否真的進入主觀下線狀態(tài)
  4. 當(dāng)有足夠數(shù)量 Sentinel(大于等于配置文件指定的值)在指定時間范圍內(nèi)確認(rèn) Master 的確進入主觀下線狀態(tài),則 Master 會被標(biāo)記為 客觀下線
  5. 若 Master 處于 ODOWN 狀態(tài),則投票自動選出新Master。將剩余從節(jié)點指向新Master繼續(xù)數(shù)據(jù)復(fù)制
  6. 在正常情況下,每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有 Master,Slave 發(fā)送 INFO 命令;當(dāng) Master 被 Sentinel 標(biāo)記為客觀下線時,Sentinel 向已下線的 Master 的所有 Slave 發(fā)送 INFO 命令的頻率會從 10 秒一次改為每秒一次;
  7. 若沒有足夠數(shù)量 Sentinel 同意 Master 已經(jīng)下線,Master 的客觀下線狀態(tài)會被移除。若 Master 重新向 Sentinel 的 PING 命令返回有效回復(fù),Master 的主觀下線狀態(tài)就會被移除

07 領(lǐng)導(dǎo)者選舉

原因:只有一個sentinel節(jié)點完成故障轉(zhuǎn)移。 選舉:通過sentinel is-master-down-by-addr命令都希望成為領(lǐng)導(dǎo)者:

  1. 每個做主觀下線的Sentinel節(jié)點向其他Sentinel節(jié)點發(fā)送命令,要求將它設(shè)置為領(lǐng)導(dǎo)者
  2. 收到命令的Sentinel節(jié)點如果沒有同意通過其他Sentinel節(jié)點發(fā)送的命令,那么將同意該請求,否則拒絕
  3. 如果該Sentinel節(jié)點發(fā)現(xiàn)自己的票數(shù)已經(jīng)超過Sentinel集合半數(shù)且超過quorum,則將成為領(lǐng)導(dǎo)者
  4. 如果此過程有多個Sentinel節(jié)點成為了領(lǐng)導(dǎo)者,那么將等待一段時間重新選舉
  • 選舉實例

08 故障轉(zhuǎn)移

8.1 領(lǐng)導(dǎo)者節(jié)點完成

  1. 從slave節(jié)點中選出一個“合適的"節(jié)點作為新的master節(jié)點
  2. 對上面的slave節(jié)點執(zhí)行slaveof no one命令讓其成為master節(jié)點
  3. 向剩余slave節(jié)點發(fā)送命令,讓它們成為新master節(jié)點的slave節(jié)點,復(fù)制規(guī)則和parallel-syncs參數(shù)有關(guān)
  4. 更新對原來master節(jié)點配置為slave,并保持著對其關(guān)注,當(dāng)其恢復(fù)后命令它去復(fù)制新的master節(jié)點。

8.2 選擇合適的slave節(jié)點

  1. 選擇slave priority(slave節(jié)點優(yōu)先級)最高的slave節(jié)點,如果存在劃返同,不存在則繼續(xù)。
  2. 選擇復(fù)制偏移量最大的slave節(jié)點(復(fù)制的最完整),若存在則返回,不存在則

繼續(xù)。 3. 選擇runId最小的slave節(jié)點。

09 常見開發(fā)運維問題

9.1 節(jié)點運維

  • 機器下線:例如過保等情況
  • 機器性能不足:例如CPU、內(nèi)存、硬盤、網(wǎng)絡(luò)等
  • 節(jié)點自身故障:例如服務(wù)不穩(wěn)定等

主節(jié)點 sentinel failover <masterName>

節(jié)點下線

  • 從節(jié)點:臨時下線還是永久下線,例如是否做一些清理工作。但是要考慮讀寫分離的情況。
  • Sentinel節(jié)點: 同上。

節(jié)點上線

  • 主節(jié)點: sentinel failover進行替換
  • 從節(jié)點: slaveof即可, sentinel節(jié)點可以感知
  • sentinel節(jié)點:參考其他sentinel節(jié)點啟動即可。

從節(jié)點的作用

  1. 副本:高可用基礎(chǔ)
  2. 拓展讀能力

由于Redis Sentinel只會對主節(jié)點進行故障轉(zhuǎn)移,對從節(jié)點采取主觀的下線,所以需要自定義一個客戶端來監(jiān)控對應(yīng)的事件

三個消息

  • +switch-master :切換主節(jié)點(從節(jié)點晉升主節(jié)點)
  • +convert-to-slave :切換從節(jié)點(原主節(jié)點降為從節(jié)點)
  • +sdown:主觀下線。

總結(jié)

  • Redis Sentinel是Redis的高可用實現(xiàn)方案:

故障發(fā)現(xiàn)、故障自動轉(zhuǎn)移、配置中心、客戶端通知。

  • Redis Sentinel從2.8版本開始才正式生產(chǎn)可用
  • 盡可能在不同物理機上部署Redis Sentinel的所有節(jié)點
  • Redis Sentinel中的Sentinel節(jié)點個數(shù)應(yīng)該≥3,且最好為奇數(shù),便于選舉
  • Redis Sentinel中的數(shù)據(jù)節(jié)點與普通數(shù)據(jù)節(jié)點無差異
  • 客戶端初始化時連接的是Sentinel節(jié)點集合,不再是具體的Redis節(jié)點,但

Sentinel只是配置中心,并非代理

  • Redis Sentinel通過三個定時任務(wù)實現(xiàn)了Sentinel節(jié)點對于主節(jié)點、從節(jié)點、

其余Sentinel節(jié)點的監(jiān)控

  • Redis Sentinel在對節(jié)點做失敗判定時分為主觀下線和客觀下線
  • 看懂Redis Sentinel故障轉(zhuǎn)移日志對于Redis Sentinel以及問題排查非常有幫助
  • Redis Sentinel實現(xiàn)讀寫分離高可用可以依賴Sentinel節(jié)點的消息通知,獲取Redis數(shù)據(jù)節(jié)點的狀態(tài)變化
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容