
- 集群監(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)移
- 多個sentinel發(fā)現(xiàn)并確認(rèn)master有問題。
- 選舉出一個sentinel作為領(lǐng)導(dǎo)。
- 選出一個slave作為master.
- 通知其余slave成為新的master的slave.
- 通知客戶端主從變化
- 等待老的master復(fù)活成為新master的slave

- 可監(jiān)控多套

03 安裝與配置
- 配置開啟主從節(jié)點
- 配置開啟sentinel監(jiān)控主節(jié)點。(sentinel是特殊的redis)
- 實際應(yīng)該多機器
- 詳細(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 客戶端接入流程
- Sentinel地址集合
- masterName
- 不是代理模式
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ù)
- 每10s 每個 sentinel 對 master 和 replica 執(zhí)行 INFO 命令
- 發(fā)現(xiàn) replica 節(jié)點
- 確認(rèn)主從關(guān)系

- 每 2s 每個 sentinel 通過 master 節(jié)點的channel交換信息(pub/sub)
- 通過 sentinel :java頻道交互
- 交互對節(jié)點的"看法”和自身信息

- 每 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 哨兵工作原理
- 每個 Sentinel 以 1次/s 向他所知的 Master,Slave 以及其他 Sentinel 節(jié)點發(fā)送一個 PING
- 若一個實例距離最后一次有效回復(fù) PING 的時間超過配置文件 down-after-milliseconds,則該實例會被 Sentinel 標(biāo)記為 主觀下線
- 若一個 Master 被標(biāo)記為主觀下線,則正在監(jiān)視該 Master 的所有 Sentinel 會 1次/s 確認(rèn) Master 是否真的進入主觀下線狀態(tài)
- 當(dāng)有足夠數(shù)量 Sentinel(大于等于配置文件指定的值)在指定時間范圍內(nèi)確認(rèn) Master 的確進入主觀下線狀態(tài),則 Master 會被標(biāo)記為 客觀下線
- 若 Master 處于 ODOWN 狀態(tài),則投票自動選出新Master。將剩余從節(jié)點指向新Master繼續(xù)數(shù)據(jù)復(fù)制
- 在正常情況下,每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有 Master,Slave 發(fā)送 INFO 命令;當(dāng) Master 被 Sentinel 標(biāo)記為客觀下線時,Sentinel 向已下線的 Master 的所有 Slave 發(fā)送 INFO 命令的頻率會從 10 秒一次改為每秒一次;
- 若沒有足夠數(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)者:
- 每個做主觀下線的Sentinel節(jié)點向其他Sentinel節(jié)點發(fā)送命令,要求將它設(shè)置為領(lǐng)導(dǎo)者
- 收到命令的Sentinel節(jié)點如果沒有同意通過其他Sentinel節(jié)點發(fā)送的命令,那么將同意該請求,否則拒絕
- 如果該Sentinel節(jié)點發(fā)現(xiàn)自己的票數(shù)已經(jīng)超過Sentinel集合半數(shù)且超過quorum,則將成為領(lǐng)導(dǎo)者
- 如果此過程有多個Sentinel節(jié)點成為了領(lǐng)導(dǎo)者,那么將等待一段時間重新選舉
- 選舉實例

08 故障轉(zhuǎn)移
8.1 領(lǐng)導(dǎo)者節(jié)點完成
- 從slave節(jié)點中選出一個“合適的"節(jié)點作為新的master節(jié)點
- 對上面的slave節(jié)點執(zhí)行slaveof no one命令讓其成為master節(jié)點
- 向剩余slave節(jié)點發(fā)送命令,讓它們成為新master節(jié)點的slave節(jié)點,復(fù)制規(guī)則和parallel-syncs參數(shù)有關(guān)
- 更新對原來master節(jié)點配置為slave,并保持著對其關(guān)注,當(dāng)其恢復(fù)后命令它去復(fù)制新的master節(jié)點。
8.2 選擇合適的slave節(jié)點
- 選擇slave priority(slave節(jié)點優(yōu)先級)最高的slave節(jié)點,如果存在劃返同,不存在則繼續(xù)。
- 選擇復(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é)點的作用
- 副本:高可用基礎(chǔ)
- 拓展讀能力

由于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)變化