一.哨兵機(jī)制
有了主從復(fù)制的實(shí)現(xiàn)以后,如果想對主服務(wù)器進(jìn)行監(jiān)控,那么在redis2.6以后提供了一個(gè)"哨兵"的機(jī)制。顧名思義,哨兵的含義就是監(jiān)控redis系統(tǒng)的運(yùn)行狀態(tài)??梢詥佣鄠€(gè)哨兵,去監(jiān)控redis數(shù)據(jù)庫的運(yùn)行狀態(tài)。其主要功能有兩點(diǎn):
- 監(jiān)控所有節(jié)點(diǎn)數(shù)據(jù)庫是否在正常運(yùn)行。
- master數(shù)據(jù)庫出現(xiàn)故障時(shí),可以自動通過投票機(jī)制,從slave節(jié)點(diǎn)中選舉新master,實(shí)現(xiàn)將從數(shù)據(jù)庫轉(zhuǎn)換為主數(shù)據(jù)庫的自動切換。
一個(gè)一主多從的Redis系統(tǒng)中,可以使用多個(gè)哨兵進(jìn)行監(jiān)控任務(wù)以保證系統(tǒng)足夠穩(wěn)健。此時(shí),不僅哨兵會同時(shí)監(jiān)控主數(shù)據(jù)庫和從數(shù)據(jù)庫,哨兵之間也會相互監(jiān)控。在這里,建議大家哨兵至少部署3個(gè),并且使用奇數(shù)個(gè)哨兵。
Redis的哨兵(sentinel) 系統(tǒng)用于管理多個(gè) Redis 服務(wù)器,該系統(tǒng)執(zhí)行以下三個(gè)任務(wù):
-
監(jiān)控(Monitoring):
哨兵(sentinel) 會不斷地檢查你的Master和Slave是否運(yùn)作正常。
-
提醒(Notification):
當(dāng)被監(jiān)控的某個(gè) Redis出現(xiàn)問題時(shí), 哨兵(sentinel) 可以通過 API 向管理員或者其他應(yīng)用程序發(fā)送通知。
-
自動故障遷移(Automatic failover):
當(dāng)一個(gè)Master不能正常工作時(shí),哨兵(sentinel) 會開始一次自動故障遷移操作,它會將失效Master的其中一個(gè)Slave升級為新的Master, 并讓失效Master的其他Slave改為復(fù)制新的Master; 當(dāng)客戶端試圖連接失效的Master時(shí),集群也會向客戶端返回新Master的地址,使得集群可以使用Master代替失效Master。
哨兵(sentinel) 是一個(gè)分布式系統(tǒng),你可以在一個(gè)架構(gòu)中運(yùn)行多個(gè)哨兵(sentinel) 進(jìn)程,這些進(jìn)程使用流言協(xié)議(gossipprotocols)來接收關(guān)于Master是否下線的信息,并使用投票協(xié)議(agreement protocols)來決定是否執(zhí)行自動故障遷移,以及選擇哪個(gè)Slave作為新的Master.
每個(gè)哨兵(sentinel) 會向其它哨兵(sentinel)、master、slave定時(shí)發(fā)送消息,以確認(rèn)對方是否”活”著,如果發(fā)現(xiàn)對方在指定時(shí)間(可配置)內(nèi)未回應(yīng),則暫時(shí)認(rèn)為對方已掛(所謂的”主觀認(rèn)為宕機(jī)” Subjective Down,簡稱sdown).
若“哨兵群”中的多數(shù)sentinel,都報(bào)告某一master沒響應(yīng),系統(tǒng)才認(rèn)為該master"徹底死亡"(即:客觀上的真正down機(jī),Objective Down,簡稱odown),通過一定的vote算法,從剩下的slave節(jié)點(diǎn)中,選一臺提升為master,然后自動修改相關(guān)配置.
雖然哨兵(sentinel) 釋出為一個(gè)單獨(dú)的可執(zhí)行文件 redis-sentinel ,但實(shí)際上它只是一個(gè)運(yùn)行在特殊模式下的 Redis 服務(wù)器,你可以在啟動一個(gè)普通 Redis 服務(wù)器時(shí)通過給定 --sentinel 選項(xiàng)來啟動哨兵(sentinel).
哨兵(sentinel) 的一些設(shè)計(jì)思路和zookeeper非常類似:
監(jiān)控
sentinel會每秒一次的頻率與之前創(chuàng)建了命令連接的實(shí)例發(fā)送PING,包括主服務(wù)器、從服務(wù)器和sentinel實(shí)例,以此來判斷當(dāng)前實(shí)例的狀態(tài)。down-after-milliseconds時(shí)間內(nèi)PING連接無效,則將該實(shí)例視為主觀下線。之后該sentinel會向其他監(jiān)控同一主服務(wù)器的sentinel實(shí)例詢問是否也將該服務(wù)器視為主觀下線狀態(tài),當(dāng)超過某quorum后將其視為客觀下線狀態(tài)。
當(dāng)一個(gè)主服務(wù)器被某sentinel視為客觀下線狀態(tài)后,該sentinel會與其他sentinel協(xié)商選出零頭sentinel進(jìn)行故障轉(zhuǎn)移工作。每個(gè)發(fā)現(xiàn)主服務(wù)器進(jìn)入客觀下線的sentinel都可以要求其他sentinel選自己為領(lǐng)頭sentinel,選舉是先到先得。同時(shí)每個(gè)sentinel每次選舉都會自增配置紀(jì)元,每個(gè)紀(jì)元中只會選擇一個(gè)領(lǐng)頭sentinel。如果所有超過一半的sentinel選舉某sentinel領(lǐng)頭sentinel。之后該sentinel進(jìn)行故障轉(zhuǎn)移操作。
如果一個(gè)Sentinel為了指定的主服務(wù)器故障轉(zhuǎn)移而投票給另一個(gè)Sentinel,將會等待一段時(shí)間后試圖再次故障轉(zhuǎn)移這臺主服務(wù)器。如果該次失敗另一個(gè)將嘗試,Redis Sentinel保證第一個(gè)活性(liveness)屬性,如果大多數(shù)Sentinel能夠?qū)υ?,如果主服?wù)器下線,最后只會有一個(gè)被授權(quán)來故障轉(zhuǎn)移。 同時(shí)Redis Sentinel也保證安全(safety)屬性,每個(gè)Sentinel將會使用不同的配置紀(jì)元來故障轉(zhuǎn)移同一臺主服務(wù)器。
故障轉(zhuǎn)移
首先是從主服務(wù)器的從服務(wù)器中選出一個(gè)從服務(wù)器作為新的主服務(wù)器。選點(diǎn)的依據(jù)依次是:網(wǎng)絡(luò)連接正常->5秒內(nèi)回復(fù)過INFO命令->10*down-after-milliseconds內(nèi)與主連接過的->從服務(wù)器優(yōu)先級->復(fù)制偏移量->運(yùn)行id較小的。選出之后通過slaveif no ont將該從服務(wù)器升為新主服務(wù)器。
通過slaveof ip port命令讓其他從服務(wù)器復(fù)制該信主服務(wù)器。
最后當(dāng)舊主重新連接后將其變?yōu)樾轮鞯膹姆?wù)器。注意如果客戶端與就主服務(wù)器分隔在一起,寫入的數(shù)據(jù)在恢復(fù)后由于舊主會復(fù)制新主的數(shù)據(jù)會造成數(shù)據(jù)丟失。
故障轉(zhuǎn)移成功后會通過發(fā)布訂閱連接廣播新的配置信息,其他sentinel收到后依據(jù)配置紀(jì)元更大來更新主服務(wù)器信息。Sentinel保證第二個(gè)活性屬性:一個(gè)可以相互通信的Sentinel集合會統(tǒng)一到一個(gè)擁有更高版本號的相同配置上。


我們可以看到哨兵機(jī)制是有缺點(diǎn)的:
主從服務(wù)器的數(shù)據(jù)要經(jīng)常進(jìn)行主從復(fù)制,這樣造成性能下降。
當(dāng)主服務(wù)器宕機(jī)后,從服務(wù)器切換成主服務(wù)器的那段時(shí)間,服務(wù)是不能用的。