一、哨兵模式概述
哨兵模式的 redis 集群有三種角色:sentinel/master/slave,它們通過 tcp 鏈接,相互建立聯系。
sentinel 作為高可用集群管理者,它的功能主要是:檢查故障,發現故障,故障轉移。
1.1 單哨兵模式 - 不推薦
1.2 多哨兵模式 - 故障轉移failover流程(重點)
- 在 redis 集群中,當 sentinel 檢測到 master(redis 主服務)出現故障,那么 sentinel 需要對集群進行故障轉移。
- 當一個 sentinel 發現 master 下線,它會將下線的 master 確認為主觀下線。
- 當“法定個數”(quorum)sentinel 已經發現該 master 節點下線,那么 sentinel 會將其確認為客觀下線。
- 多個 sentinel 根據一定的邏輯(詳見1.3 多哨兵模式 - sentinel哨兵選舉規則),選舉出一個 sentinel 作為 leader
- 由sentinel leader去進行故障轉移,將原來連接已客觀下線 master 最優的一個 slave 提升為新 master 角色。舊 master 如果重新激活,它將被降級為 slave。
1.3 多哨兵模式 - sentinel哨兵選舉規則 (重點)
- 每個在線的sentinel節點都可以成為領導者leader sentinel。當某個sentinel確認redis主服務master下線時,會向其他sentinel 哨兵發 is-master-down-by-addr 命令,征求判斷並要求將自己設置為領導者,由領導者處理故障轉移;
- 當其他哨兵收到此命令時,可以同意或者拒絕它成為領導者;
- 如果競爭成為leader的sentinel哨兵,發現自己在選舉的票數大於等於哨兵的個數/2+1時,並且其數量也超過了設定的quoram參數,將會成為領導者。如果沒有超過,或者多個哨兵同時參與這個選舉,那么就會重復該過程,直到選出一個leader領頭sentinel哨兵。
1.4 哨兵模式優缺點
二、腦裂現象
2.1 什么是腦裂?
所謂腦裂問題(類似於精神分裂),就是同一個集群中的不同節點,對於集群的狀態有了不一樣的理解。
2.2 哨兵模式如何造成腦裂現象?
redis集群的三個角色:
- M :redis 主服務 master
- R :redis 副本 replication/slave
- S :redis 哨兵 sentinel
sentinel 配置 quorum = 1
,也就是一個 sentinel 發現故障,也可以選舉自己為 leader,進行故障轉移。
下面的部署:兩個機器,分別部署了 redis 的三個角色
+----+ +----+ | M1 |---------| R1 | | S1 | | S2 | +----+ +----+
因為某種原因,兩個機器斷開鏈接,S2 將同機器的 R1 提升角色為 master,這樣集群里,出現了兩個 master 同時工作 —— 腦裂出現了。不同的 client 鏈接到不同的 redis 進行讀寫,那么兩台機器就出現了 redis 數據不一致的現象。
+----+ +------+ | M1 |----//-----| [M1] | | S1 | | S2 | +----+ +------+
2.3 怎么解決腦裂現象?
通過合理部署配置 sentinel/master,降低腦裂出現概率。
通過sentienl 配置解決
合理部署 sentinel 的節點個數,以及配置 sentinel 選舉的法定人數。
- sentinel 節點個數最好 >= 3。
- sentinel 節點個數最好是基數。
- sentinel 的選舉法定人數設置為 (n/2 + 1)。
配置
# sentinel.conf
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
quorum
- <quorum> 是
法定人數
。作用:多個 sentinel 進行相互選舉,有超過法定人數
的 sentinel 選舉某個 sentinel 為 leader,那么他就成為 leader, leader 負責故障轉移。這個法定人數,可以配置,一般是 sentinel 個數一半以上 (n/2 + 1) 比較合理。 - 如果 sentinel 個數總數為 3,那么最好 quorum == 2,這樣最接近真實:少數服從多數,不會出現兩個票數一樣的 leader同時被選上,進行故障轉移。
# sentinel.conf sentinel monitor mymaster >127.0.0.1 6379 2
通過master 配置解決
如果 master 因為某些原因與一定數量的副本失去聯系了,通過修改 master 配置項,可以禁止 client 向故障的 master 寫數據。
1. 依然存在的問題
按照上述的 sentinel 部署方案,下面三個機器,任何一個機器出現問題,只要兩個 sentinel 能相互鏈接,故障轉移是正常的。
+----+ | M1 | | S1 | +----+ | +----+ | +----+ | R2 |----+----| R3 | | S2 | | S3 | +----+ +----+ Configuration: quorum = 2
假如 M1 機器與其它機器斷開鏈接了,S2 和 S3 兩個 sentinel 能相互鏈接,sentinel 能正常進行故障轉移,sentinel leader 將 R2 提升為新的 master 角色 [M2]。但是客戶端 C1 仍然能讀寫 M1,這樣仍然會出現問題,所以我們不得不對 M1 進行限制。
+----+
| M1 |
| S1 | <- C1 (writes will be lost)
+----+
|
/
/
+------+ | +----+
| [M2] |----+----| R3 |
| S2 | | S3 |
+------+ +----+
2.解決方案
限制 M1 比較簡單的方案,通過修改 redis 配置 redis.conf,檢查 master 節點與其它副本的聯系。當 master 發現它的副本下線或者通信超時的總數量小於閾值時,那么禁止 master 進行寫數據。
但是這個方案也不是完美的,min-slaves-to-write 依賴於副本的鏈接個數,如果 slave 個數設置不合理,那么集群很難故障轉移成功。
redis.conf配置
# master 須要有至少 x 個副本連接。 min-slaves-to-write x # 數據復制和同步的延遲不能超過 x 秒。 min-slaves-max-lag x
測試
測試 - 單哨兵模式
最后的“1”,代表當“1”的哨兵認為主機宕機時,該主機才被判定為宕機。如果配置了多哨兵模式,比如三個哨兵,該數字一般會設置為2、3.
1. 哨兵配置文件
2. 啟動哨兵
測試 - 多哨兵模式