掌握Redis的Sentinel哨兵原理,助你拿到25k的offer!

1 Redis Sentinel的意義

  • master宕機了咋整?等運維手工從主切換,再通知全部程序把地址通通改一遍從新上線?那麼服務就會停滯好久,顯然對於大型系統這是災難性的!

因此必須有高可用方案,當故障發生時可自動從主切換,程序也不用重啓,沒必要手動運維。Redis 官方就提供了這樣一種方案 —— Redis Sentinel(哨兵)。java

sentinal,哨兵,redis集羣架構中很是重要的一個組件,主要功能以下node

  • 集羣監控

監控Redis master和slave進程的正常工做git

  • 消息通知

若是某個Redis實例有故障,那麼哨兵負責發送報警消息給管理員github

  • 故障轉移

若master node宕機,會自動轉移到slave node上redis

  • 配置中心

若發生故障轉移,通知client客戶端新的master地址算法

哨兵自己也是分佈式,做爲一個集羣運行:bash

  • 故障轉移時,判斷一個master node是否宕機,須要大部分哨兵都贊成,涉及分佈式選舉
  • 即便部分哨兵節點宕機,哨兵集羣仍是能正常工做

目前採用的是sentinal 2版本,sentinal 2相對於sentinal 1來講,重寫了不少代碼,主要是讓故障轉移的機制和算法變得更加健壯和簡單服務器

哨兵 + Redis主從的部署架構不保證數據零丟失,只保證redis集羣的高可用性。markdown

爲什麼2個節點沒法正常工做

必須部署2個以上的節點。若僅部署2個實例,quorum=1網絡

+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+
複製代碼

Configuration: quorum = 1

master宕機,s1和s2中只要有1個哨兵認爲master宕機就能夠進行切換,同時會在s1和s2中選舉出一個執行故障轉移. 但此時,須要majority,也就是大多數哨兵都是運行的,2個哨兵的majority就是2

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

2個哨兵都運行着,就能夠容許執行故障轉移

若整個M1和S1運行的機器宕機了,那麼哨兵僅剩1個,此時就無majority來容許執行故障轉移,雖然另一臺機器還有一個R1,但故障轉移不會執行

3節點哨兵集羣

+----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+
複製代碼

Configuration: quorum = 2,majority

若M1節點宕機了,還剩下2個哨兵,S2和S3能夠一致認爲master宕機了,而後選舉出一個來執行故障轉移

同時3個哨兵的majority是2,因此餘存的2個哨兵運行着,就可執行故障轉移

2 Redis Sentinel 架構

Redis Sentinel故障轉移

  1. 多個sentinel發現並確認master有問題。
  2. 選舉出一個sentinel做爲領導。
  3. 選出一個slave做爲master.
  4. 通知其他slave成爲新的master的slave.
  5. 通知客戶端主從變化
  6. 等待老的master復活成爲新master的slave

  • 可監控多套

3 安裝與配置

  1. 配置開啓主從節點
  2. 配置開啓sentinel監控主節點。(sentinel是特殊的redis)
  3. 實際應該多機器
  4. 詳細配置節點

Redis 主節點

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

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

Redis 從節點

[啓動]
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
複製代碼

演示

  • 主節點配置

  • 重定向
  • 打印檢查配置文件
  • 啓動

4 客戶端

  • 客戶端實現基本原理-1

  • 客戶端實現基本原理-2

  • 客戶端實現基本原理-3 驗證
  • 客戶端實現基本原理-4 通知(發佈訂閱))

客戶端接入流程

  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();
}
複製代碼

5 定時任務

  1. 每10s 每一個 sentinel 對 master 和 replica 執行 INFO 命令
  • 發現 replica 節點
  • 確認主從關係

  1. 每 2s 每一個 sentinel 經過 master 節點的channel交換信息(pub/sub)
  • 經過 sentinel :java頻道交互
  • 交互對節點的"見解」和自身信息

  1. 每 1s 每一個 sentinel 對其餘 sentinel 和 redis 執行ping
  • 心跳檢測,失敗斷定依據

6 主觀下線和客觀下線

主觀下線(Subjectively Down,SDOWN)

單個 Sentinel 節點對服務器作出的下線判斷,即單個 Sentinel 認爲某個服務下線(有多是接收不到訂閱,之間的網絡不通等一系列緣由)。

注意主觀下線是每一個sentinel節點對Redis節點失敗的"偏見」。因此還須要客觀下線機制。

客觀下線(Objectively Down,ODOWN)

多個 Sentinel 實例在對同一個服務器作出 SDOWN 判斷,而且經過命令互相交流以後,得出的服務器下線判斷,而後開啓 failover。

只有在足夠數量( 超過quorum個)的 Sentinel 都將一個服務器標記爲主觀下線以後, 服務器纔會被標記爲客觀下線(ODOWN)。只有當 Master 被認定爲客觀下線時,纔會發生故障遷移。

仲裁

仲裁指配置文件中的 quorum 參數。某個 Sentinel 先將 Master 節點標記爲主觀下線,而後會將這個斷定經過 sentinel is-master-down-by-addr 命令詢問其餘 Sentinel 節點是否也一樣認爲該 addr 的 Master 節點要作主觀下線。

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
複製代碼

最後當達成這一共識的 Sentinel 個數達到前面說的 quorum 設置的值時,該 Master 節點會被認定爲客觀下線並進行故障轉移。 quorum 值通常設爲 Sentinel 個數的二分之一加 1,例如 3 個 Sentinel 就設爲 2。

綜上可得

哨兵工做原理

  1. 每一個 Sentinel 以 1次/s 向它所知的 Master,Slave 以及其餘 Sentinel 節點發送一個 PING
  2. 若一個實例距離最後一次有效回覆 PING 的時間超過配置文件 down-after-milliseconds,則該實例會被 Sentinel 標記爲 主觀下線
  3. 若一個 Master 被標記爲主觀下線,則正在監視該 Master 的全部 Sentinel 會 1次/s 確認 Master 是否真的進入主觀下線狀態
  4. 當有足夠數量 Sentinel(大於等於配置文件指定的值)在指定時間範圍內確認 Master 的確進入主觀下線狀態,則 Master 會被標記爲 客觀下線
  5. 若 Master 處於 ODOWN 狀態,則投票自動選出新Master。將剩餘從節點指向新Master繼續數據複製
  6. 在正常狀況下,每一個 Sentinel 會以每 10 秒一次的頻率向它已知的全部 Master,Slave 發送 INFO 命令;當 Master 被 Sentinel 標記爲客觀下線時,Sentinel 向已下線的 Master 的全部 Slave 發送 INFO 命令的頻率會從 10 秒一次改成每秒一次;
  7. 若沒有足夠數量 Sentinel 贊成 Master 已經下線,Master 的客觀下線狀態會被移除。若 Master 從新向 Sentinel 的 PING 命令返回有效回覆,Master 的主觀下線狀態就會被移除。

7 領導者選舉

緣由:只有一個sentinel節點完成故障轉移。 選舉:經過sentinel is-master-down-by-addr命令都但願成爲領導者:

  1. 每一個作主觀下線的Sentinel節點向其餘Sentinel節點發送命令,要求將它設置爲領導者
  2. 收到命令的Sentinel節點若是沒有贊成經過其餘Sentinel節點發送的命令,那麼將贊成該請求,不然拒絕
  3. 若是該Sentinel節點發現本身的票數已經超過Sentinel集合半數且超過quorum,則將成爲領導者
  4. 若是此過程有多個Sentinel節點成爲了領導者,那麼將等待一段時間從新選舉
  • 選舉實例

8 故障轉移

領導者節點完成

  1. 從slave節點中選出一個「合適的"節點做爲新的master節點
  2. 對上面的slave節點執行slaveof no one命令讓其成爲master節點
  3. 向剩餘slave節點發送命令,讓它們成爲新master節點的slave節點,複製規則和parallel-syncs參數有關
  4. 更新對原來master節點配置爲slave,並保持着對其關注,當其恢復後命令它去複製新的master節點。

選擇合適的slave節點

  1. 選擇slave priority(slave節點優先級)最高的slave節點,若是存在劃返同,不存在則繼續。
  2. 選擇複製偏移量最大的slave節點(複製的最完整),若存在則返回,不存在則

繼續。 3. 選擇runId最小的slave節點。

常見開發運維問題

節點運維

  • 機器下線:例如過保等狀況
  • 機器性能不足:例如CPU、內存、硬盤、網絡等
  • 節點自身故障:例如服務不穩定等

主節點 sentinel failover <masterName>

節點下線

  • 從節點:臨時下線仍是永久下線,例如是否作一些清理工做。可是要考慮讀寫分離的狀況。
  • Sentinel節點: 同上。

節點上線

  • 主節點: sentinel failover進行替換
  • 從節點: slaveof便可, sentinel節點能夠感知
  • sentinel節點:參考其餘sentinel節點啓動便可。

從節點的做用

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

因爲Redis Sentinel只會對主節點進行故障轉移,對從節點採起主觀的下線,因此須要自定義一個客戶端來監控對應的事件

三個消息

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

總結

  • Redis Sentinel是Redis的高可用實現方案:

故障發現、故障自動轉移、配置中心、客戶端通知。

  • Redis Sentinel從2.8版本開始才正式生產可用
  • 儘量在不一樣物理機上部署Redis Sentinel的全部節點
  • Redis Sentinel中的Sentinel節點個數應該≥3,且最好爲奇數,便於選舉
  • Redis Sentinel中的數據節點與普通數據節點無差別
  • 客戶端初始化時鏈接的是Sentinel節點集合,再也不是具體的Redis節點,但

Sentinel只是配置中心,並不是代理

  • Redis Sentinel經過三個定時任務實現了Sentinel節點對於主節點、從節點、

其他Sentinel節點的監控

  • Redis Sentinel在對節點作失敗斷定時分爲主觀下線和客觀下線
  • 看懂Redis Sentinel故障轉移日誌對於Redis Sentinel以及問題排查很是有幫助
  • Redis Sentinel實現讀寫分離高可用能夠依賴Sentinel節點的消息通知,獲取Redis數據節點的狀態變化

參考

相關文章
相關標籤/搜索