Redis Sentinel 是 Redis官方提供的高可用解決方案。Redis本身可以實(shí)現(xiàn)主從復(fù)制,但是并沒有自動(dòng)切換主備的功能,當(dāng)出現(xiàn)其中一個(gè)主實(shí)例宕機(jī)的情況,客戶端將無法執(zhí)行寫入命令,Sentinel可以在沒有人工干預(yù)的情況下執(zhí)行故障轉(zhuǎn)移,不影響正常的寫入操作。Sentinel是一個(gè)分布式的系統(tǒng),多個(gè)Sentinel進(jìn)程之間協(xié)調(diào)工作,一來保證故障檢測(cè)的誤報(bào)率,二來保證了Sentinel本身的可用性。
Sentinel提供了以下功能:
- 監(jiān)控。Sentinel會(huì)不斷檢查主從是否按預(yù)期工作。
- 通知。Sentinel可以通過API通知系統(tǒng)管理員,另一臺(tái)計(jì)算機(jī)程序,其中一個(gè)受監(jiān)控的Redis實(shí)例出現(xiàn)問題。
- 自動(dòng)故障轉(zhuǎn)移。如果主服務(wù)器未按預(yù)期工作,Sentinel可以啟動(dòng)故障轉(zhuǎn)移過程,其中從服務(wù)器升級(jí)為主服務(wù)器,其他其他服務(wù)器重新配置為使用新主服務(wù)器,并且使用Redis服務(wù)器的應(yīng)用程序通知有關(guān)新服務(wù)器的地址連接。
- 配置提供商。Sentinel充當(dāng)客戶端服務(wù)發(fā)現(xiàn)的權(quán)限來源:客戶端連接到Sentinels,以便詢問負(fù)責(zé)給定服務(wù)的當(dāng)前Redis主服務(wù)器的地址。如果發(fā)生故障轉(zhuǎn)移,Sentinels將報(bào)告新地址。
配置
我挑了一些主要的配置項(xiàng)出來,其它的都與redis.conf類似
# sentinel announce-ip <ip>
# sentinel announce-port <port>
sentinel auth-pass mymaster <password>
# sentinel monitor <master-group-name> <ip> <port> <quorm>
sentinel monitor mymaster 127.0.0.1 6379 2
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000
# sentinel parallel-syncs <master-name> <numreplicas>
sentinel parallel-syncs mymaster 1
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
-
sentinel auth-pass <master-group-name> <password>
,配置主服務(wù)器的密碼 -
sentinel monitor <master-group-name> <ip> <port> <quorm>
,配置需要監(jiān)視的主服務(wù)器,最后一個(gè)為仲裁參數(shù)
,代表Sentinel集群中必須有至少2個(gè)實(shí)例認(rèn)為主服務(wù)器不可用,其中一個(gè)嘗試啟動(dòng)故障轉(zhuǎn)移,默認(rèn)127.0.0.1 6379 2
-
sentinel down-after-milliseconds <master-name> <milliseconds>
, 主服務(wù)器未回復(fù)sentinel ping的時(shí)長(zhǎng),如果超過這個(gè)時(shí)長(zhǎng),則這個(gè)sentinel實(shí)例主觀的認(rèn)為主服務(wù)器不可用,默認(rèn)3000
-
sentinel parallel-syncs <master-name> <numreplicas>
, 設(shè)置可在同一故障轉(zhuǎn)移后重新配置以使用新主服務(wù)器的從服務(wù)器數(shù),默認(rèn)1
-
sentinel failover-timeout <master-name> <milliseconds>
,指定故障轉(zhuǎn)移超時(shí)時(shí)長(zhǎng),默認(rèn)180000
啟動(dòng)
可以通過以下兩種方式開啟Sentinel:
redis-server sentinel.conf --sentinel
或
redis-sentinel sentinel.conf
Sentinel 解析
任何一個(gè)sentinel實(shí)例主要達(dá)到SDOWN的條件,就將該服務(wù)器標(biāo)記為 SDOWN,如果有至少 qurom
個(gè)實(shí)例都認(rèn)為該服務(wù)器SDOWN,就標(biāo)記為 ODOWN,此時(shí)觸發(fā)故障轉(zhuǎn)移,需要滿足大多數(shù)Sentinel實(shí)例的授權(quán)才能進(jìn)行故障轉(zhuǎn)移。例設(shè)有5個(gè)sentinel 實(shí)例,配置 qurom 為 2 , 5個(gè)實(shí)例,有2個(gè)認(rèn)為服務(wù)器無法訪問,就嘗試故障轉(zhuǎn)移,只有3個(gè)或以上實(shí)例授權(quán)后才能執(zhí)行故障轉(zhuǎn)移,如果qurom設(shè)置為5,則當(dāng)ODOWN時(shí),直接進(jìn)行故障轉(zhuǎn)移。
Sentinel 實(shí)例之間的通信
Sentinel 實(shí)例之間通過名為 __sentinel__:hello
的 Pub/Sub channel 進(jìn)行通信
- 每個(gè) Sentinel 每隔2秒向 channel 中發(fā)送 ip port runid 宣布它的存在
- 每個(gè) Sentinel 訂閱 channel ,當(dāng)檢測(cè)到新的 Sentinel 后,將它添加進(jìn)集群中
- 消息中包括完整的當(dāng)前服務(wù)器的配置,如果某個(gè)Sentinel 還是舊的服務(wù)器的配置,將會(huì)立刻更新
- 在向主服務(wù)器添加新的標(biāo)記之前,Sentinel始終檢查是否已存在具有相同runid或相同地址(ip和端口對(duì))的標(biāo)記。在這種情況下,將刪除所有匹配的標(biāo)記,并添加新的標(biāo)記。
SDOWN 和 ODOWN狀態(tài)
- Subjectively Down(SDOWN,主觀下線),單個(gè)實(shí)例對(duì)服務(wù)器做出的下線判斷
- Objectively Down(ODOWN,客觀下線),多個(gè)實(shí)例對(duì)同一個(gè)服務(wù)器做出的下線判斷,并且多個(gè)實(shí)例之間已經(jīng)通過
SENTINEL is-master-down-by-addr
交流之后做出的下線判斷。
Sentinel 每隔1秒向服務(wù)器發(fā)出 ping 命令,如果服務(wù)器距離上次回復(fù)ping 已經(jīng)超過了 down-after-milliseconds
所設(shè)置的時(shí)長(zhǎng),或者不是以下三個(gè)中的命令時(shí),sentinel 認(rèn)為這個(gè)服務(wù)器下線了(主觀下線):
- +PONG
- -LOADING
- -MASTERDOWN
當(dāng)多個(gè)sentinel實(shí)例(qurom)對(duì)同一個(gè)服務(wù)器做出主觀下線的判斷后,狀態(tài)變?yōu)?ODOWN
Slave 選擇和優(yōu)先權(quán)
當(dāng)Sentinel開始執(zhí)行故障轉(zhuǎn)移時(shí),需要在 從服務(wù)器之間選出一個(gè),來提升為主服務(wù)器,只要參考以下4個(gè)方面:
- 與原主服務(wù)器斷開連接的時(shí)長(zhǎng)
- Slave priority,在 redis.conf 中有配置
slave-priority
,默認(rèn)為100,數(shù)字越小將越優(yōu)先 - 已經(jīng)處理的復(fù)制偏移量
- Run ID
分區(qū)下的一致性
+-------------+
| Sentinel 1 | <--- Client A
| Redis 1 (M) |
+-------------+
|
|
+-------------+ | +------------+
| Sentinel 2 |-----+-- / partition / ----| Sentinel 3 | <--- Client B
| Redis 2 (S) | | Redis 3 (M)|
+-------------+ +------------+
初始狀態(tài)下redis3是master, redis1和redis2是slave。之后redis3所在的主機(jī)網(wǎng)絡(luò)不可用了,sentinel1和sentinel2啟動(dòng)了failover并把redis1選舉為master。
Sentinel集群的特性保證了sentinel1和sentinel2得到了關(guān)于master的最新配置。但是sentinel3依然持著的是舊的配置,因?yàn)樗c外界隔離了。
客戶端將依然可以向redis3寫數(shù)據(jù),但是當(dāng)網(wǎng)絡(luò)恢復(fù)后,redis3就會(huì)變成redis的一個(gè)slave,那么,在網(wǎng)絡(luò)隔離期間,客戶端向redis3寫的數(shù)據(jù)將會(huì)丟失。
如果你把redis當(dāng)做緩存來使用,那么你也許能容忍這部分?jǐn)?shù)據(jù)的丟失。
但如果你把redis當(dāng)做一個(gè)存儲(chǔ)系統(tǒng)來使用,你也許就無法容忍這部分?jǐn)?shù)據(jù)的丟失了。
因?yàn)閞edis采用的是異步復(fù)制,在這樣的場(chǎng)景下,沒有辦法避免數(shù)據(jù)的丟失。然而,你可以通過以下配置來配置redis3和redis1,使得數(shù)據(jù)不會(huì)丟失。
可以通過下面2個(gè)參數(shù)進(jìn)行配置,保證只要有一個(gè)從服務(wù)器斷開了與主服務(wù)器的連接就不執(zhí)行寫入操作。具體可以參考 Redis從入門到精通(六、Redis主從復(fù)制)
min-slaves-to-write 1
min-slaves-max-lag 10
Sentinel persistent state
Sentinel狀態(tài)保留在sentinel配置文件中。這意味著停止并重新啟動(dòng)Sentinel進(jìn)程是安全的。
更多詳細(xì)資料參考: