??每日一句
最美好的生活方式是和一群志同道合的人贪壳,一起奔跑在理想的路上粪小,回頭有一路的故事瘟判,低頭有堅(jiān)定的腳步,抬頭有清晰的遠(yuǎn)方整胃!
?? Sentinel存在的意義
?? Sentinel出現(xiàn)的前提背景
在前面Redis技術(shù)系列的章節(jié)中颗圣,我們介紹了相關(guān)Redis持久化機(jī)制和Redis主從架構(gòu)的探究。兩者的相輔相成實(shí)現(xiàn)了Redis的數(shù)據(jù)高可用性以及服務(wù)的可擴(kuò)展性和負(fù)載性屁使,但是只依靠持久化方案和主從復(fù)制能力(負(fù)載和數(shù)據(jù)的榮譽(yù))在岂,在出現(xiàn)服務(wù)宕機(jī)的時(shí)候,故障切換無法自動(dòng)去實(shí)現(xiàn)蛮寂,還需要手工蔽午,這對(duì)人工成本造成了巨大的損失以及不穩(wěn)定性。
?? 持久化+主從復(fù)制后的仍存在的痛點(diǎn)
當(dāng) 主服務(wù)器下線后無法恢復(fù)服務(wù)使用主從復(fù)制酬蹋,在master節(jié)點(diǎn)下線后及老,只能夠手動(dòng)將 slave 節(jié)點(diǎn)切換為 master抽莱,但是不能自動(dòng)完成故障轉(zhuǎn)移。
?? Sentinel的加入才夠完整
Sentinel(哨兵)是Redis的高可用性解決方案:由一個(gè)或多個(gè)Sentinel實(shí)例組成的Sentinel系統(tǒng)可以監(jiān)視任意多個(gè)主服務(wù)器骄恶,以及這些主服務(wù)器屬下的所有從服務(wù)器岸蜗,并在被監(jiān)視的主服務(wù)器進(jìn)入下線狀態(tài)時(shí),自動(dòng)將下線主服務(wù)器屬下的某個(gè)從服務(wù)器升級(jí)為新的主服務(wù)器叠蝇。
主從持久化機(jī)制與加入哨兵之后的對(duì)比:
??Sentinel的主要功能
Redis Sentinel為Redis提供了完整的高可用解決方案璃岳。實(shí)際上這意味著使用Sentinel可以部署一套R(shí)edis,在沒有人為干預(yù)的情況下去應(yīng)付各種各樣的失敗事件悔捶。同時(shí)提供了一些其他的功能铃慷,例如:監(jiān)控、通知蜕该、并為client提供配置犁柜。
??Sentinel的概念定義
Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案 ,當(dāng)用Redis做Master-slave的高可用方案時(shí)堂淡,假如master宕機(jī)了馋缅,Redis本身(包括它的很多客戶端)都沒有實(shí)現(xiàn)自動(dòng)進(jìn)行主備切換,而Redis-sentinel本身也是一個(gè)獨(dú)立運(yùn)行的進(jìn)程绢淀,它能監(jiān)控多個(gè)master-slave集群萤悴,發(fā)現(xiàn)master宕機(jī)后能進(jìn)行自動(dòng)切換。
Redis從 2.8發(fā)布了一個(gè)穩(wěn)定版本的Redis Sentinel 皆的。當(dāng)前版本的 Sentinel稱為Sentinel 2覆履。它是使用更強(qiáng)大和更簡單的預(yù)測算法來重寫初始Sentinel實(shí)現(xiàn)。(Redis2.6版本提供Sentinel 1版本费薄,但是有 一些問題)硝全。
??Sentinel的功能分布
監(jiān)控(Monitoring):Sentinel會(huì)不斷的檢查你的主節(jié)點(diǎn)和從節(jié)點(diǎn)是否正常工作。
通知(Notification):被監(jiān)控的Redis實(shí)例如果出現(xiàn)問題楞抡,Sentinel可以通過API(pub)通知系統(tǒng)管理員或者其他程序伟众。
自動(dòng)故障轉(zhuǎn)移(Automatic failover):如果一個(gè)主節(jié)點(diǎn)沒有按照預(yù)期工作,Sentinel 會(huì)開始進(jìn)行故障轉(zhuǎn)移召廷,把一個(gè)從節(jié)點(diǎn)提升為主節(jié)點(diǎn)凳厢,并重新配置其他的從節(jié)點(diǎn)使用新的主節(jié)點(diǎn),其他的從節(jié)點(diǎn)會(huì)開始復(fù)制新的主節(jié)點(diǎn)柱恤,并且使用Redis服務(wù)的應(yīng)用程序在連接的時(shí)候也被通知新的地址数初。
配置提供(Configuration provider):客戶端可以把 Sentinel 作為權(quán)威的配置發(fā)布者來獲得最新的maste 地址找爱。如果發(fā)生了故障轉(zhuǎn)移梗顺,Sentinel集群會(huì)通知客戶端新的master地址,并刷新 Redis 的配置车摄。(sentinel會(huì)返回最新的master地址)
??Sentinel的分布特性
如果只使用單個(gè)sentinel進(jìn)程來監(jiān)控redis集群是不可靠的寺谤,當(dāng)sentinel進(jìn)程宕掉后(sentinel本身也有單點(diǎn)問題仑鸥,single-point-of-failure)整個(gè)集群系統(tǒng)將無法按照預(yù)期的方式運(yùn)行。所以有必要將sentinel集群变屁。
Redis Sentinel是一個(gè)分布式系統(tǒng)眼俊,Sentinel運(yùn)行在有許多Sentinel進(jìn)程互相合作的環(huán)境下,它本身就是這樣被設(shè)計(jì)的粟关。有許多Sentinel進(jìn)程互相合作的優(yōu)點(diǎn)如下:
當(dāng)多個(gè)Sentinel同意一個(gè)master不再可用的時(shí)候疮胖,就執(zhí)行故障檢測。這明顯降低了錯(cuò)誤概率闷板。
即使并非全部的Sentinel都在工作澎灸,Sentinel也可以正常工作,這種特性遮晚,讓系統(tǒng)非常的健康(最好是奇數(shù)個(gè)性昭,因?yàn)椴蝗菀走x舉成為同票)。
分布方式總體深入下圖所示:
??Sentinel的基本原理
總體而言:多個(gè) Sentinel 進(jìn)程(progress)县遣, 這些進(jìn)程使用流言協(xié)議(gossip protocols)來 接收關(guān)于主服務(wù)器是否下線的信息糜颠, 并使用投票協(xié)議(agreement protocols)來決定是否執(zhí)行自動(dòng)故障遷移, 以及選擇哪個(gè)從服務(wù)器作為新的主服務(wù)器萧求。
??Sentinel的主觀下線(SDOWN)
一個(gè)服務(wù)器必須在 master-down-after-milliseconds 毫秒內(nèi)其兴, 一直返回?zé)o效回復(fù)才會(huì)被 Sentinel 標(biāo)記為主觀下線。
在Sentinel哨兵的運(yùn)行階段夸政,(其會(huì)向其他的Sentinel哨兵忌警、master和slave發(fā)送消息確認(rèn)其是否存活),如果在指定的時(shí)間內(nèi)未收到正趁胧幔回應(yīng)法绵,暫時(shí)認(rèn)為對(duì)方掛起了(被標(biāo)記為主觀宕機(jī)–SDOWN)。
【注意:當(dāng)只有單個(gè)sentinel實(shí)例對(duì)redis實(shí)例做出無響應(yīng)的判斷酪碘,此時(shí)進(jìn)入主觀判斷朋譬,不會(huì)觸發(fā)自動(dòng)故障轉(zhuǎn)移等操作。】
【注意:一個(gè)服務(wù)器必須在 master-down-after-milliseconds 毫秒內(nèi)兴垦, 一直返回?zé)o效回復(fù)才會(huì)被 Sentinel 標(biāo)記為主觀下線】
??Sentinel的客觀下線(ODOWN)
當(dāng)多個(gè)Sentinel哨兵(數(shù)量由quorum參數(shù)設(shè)定)都報(bào)告同一個(gè)master沒有響應(yīng)了徙赢,通過投票算法(Raft算法),系統(tǒng)判斷其已死亡(被標(biāo)記為客觀宕機(jī)–ODOWN)探越。
多個(gè) Sentinel 實(shí)例在對(duì)同一個(gè)服務(wù)器做出 SDOWN 判斷狡赐, 并且通過 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服務(wù)器下線判斷钦幔。
Sentinel可以通過向另一個(gè) Sentinel 發(fā)送 SENTINEL is-master-down-by-addr 命令來詢問對(duì)方是否認(rèn)為給定的服務(wù)器已下線枕屉。
??Sentinel下線操作
從主觀下線狀態(tài)切換到客觀下線狀態(tài)并沒有使用嚴(yán)格的法定人數(shù)算法(strong quorum algorithm), 而是使用了流言協(xié)議: 如果 Sentinel 在給定的時(shí)間范圍內(nèi)(master_down_after_milliseconds)鲤氢, 從其他 Sentinel 那里接收到了足夠數(shù)量的主服務(wù)器下線報(bào)告搀擂, 那么 Sentinel 就會(huì)將主服務(wù)器的狀態(tài)從主觀下線改變?yōu)榭陀^下線西潘。 如果之后其他 Sentinel 不再報(bào)告主服務(wù)器已下線, 那么客觀下線狀態(tài)就會(huì)被移除哨颂。
客觀下線條件只適用于主服務(wù)器: 對(duì)于任何其他類型的 Redis 實(shí)例(其他sentinel和slave服務(wù)節(jié)點(diǎn))喷市, Sentinel 在將它們判斷為下線前不需要進(jìn)行協(xié)商, 所以從服務(wù)器Slave或者其他 Sentinel 永遠(yuǎn)不會(huì)達(dá)到客觀下線條件威恼。
??Sentinel的主從切換
- 此時(shí)Sentinel集群會(huì)選取領(lǐng)頭的哨兵(leader)進(jìn)行故障恢復(fù)品姓,從現(xiàn)有slave節(jié)點(diǎn)中選出(算法后續(xù)有介紹)一個(gè)提升為Master,并把剩余Slave都指向新的Master箫措,繼續(xù)維護(hù)主從關(guān)系缭黔。
??Sentinel自動(dòng)發(fā)現(xiàn)機(jī)制
-
那么,Sentinel集群的機(jī)器是如何發(fā)現(xiàn)集群中的其他機(jī)器呢蒂破?
- 使用廣播馏谨?很顯然不合適,既然是redis的產(chǎn)品附迷,自然要充分運(yùn)用redis功能惧互,Sentinel集群節(jié)點(diǎn)利用了Redis master的發(fā)布/訂閱機(jī)制去自動(dòng)發(fā)現(xiàn)其它節(jié)點(diǎn)。
每個(gè)Sentinel使用發(fā)布/訂閱的方式持續(xù)地傳播master的配置版本信息喇伯,配置傳播的發(fā)布/訂閱管道是: sentinel:hello喊儡,我們可以通過訂閱其頻道查看頻道中的消息,如下:
?? Sentinel 利用 pub/sub(發(fā)布/訂閱):
訂閱了每個(gè) master 和 slave 數(shù)據(jù)節(jié)點(diǎn)的 sentinel:hello 頻道稻据,去自動(dòng)發(fā)現(xiàn)其它也監(jiān)控了統(tǒng)一 master 的 sentinel 節(jié)點(diǎn)艾猜,Sentinel 向每 1s 向 sentinel:hello 中發(fā)送一條消息,包含了其當(dāng)前維護(hù)的最新的master 配置捻悯。
如果某個(gè)sentinel發(fā)現(xiàn)自己的配置版本低于接收到的配置版本匆赃,則會(huì)用新的配置更新自己的 master 配置與發(fā)現(xiàn)的 Sentinel 之間相互建立命令連接,之后會(huì)通過這個(gè)命令連接來交換對(duì)于 master 數(shù)據(jù)節(jié)點(diǎn)的看法今缚。
sentinel的狀態(tài)會(huì)被持久化地寫入sentinel的配置文件中算柳。每次當(dāng)收到一個(gè)新的配置時(shí),或者新創(chuàng)建一個(gè)配置時(shí)姓言,配置會(huì)被持久化到硬盤中瞬项,并帶上配置的版本戳。這意味著何荚,可以安全的停止和重啟sentinel進(jìn)程囱淋。
??Sentinel的發(fā)現(xiàn)方式
原理中提及到了,當(dāng)sentinel發(fā)現(xiàn)主庫客觀下線時(shí)候會(huì)進(jìn)行領(lǐng)頭哨兵選舉(超過半數(shù)切大于閾值)進(jìn)行故障恢復(fù)餐塘,其選舉算法采用Raft算法妥衣,這也為什么說其設(shè)計(jì)思想類似與zookpeer,選舉過程大體如下:
發(fā)現(xiàn)主庫客觀下線的哨兵節(jié)點(diǎn)(這里稱為A)向每個(gè)哨兵節(jié)點(diǎn)發(fā)送命令要求對(duì)方選舉自己為領(lǐng)頭哨兵(leader);
如果目標(biāo)哨兵沒有選舉過其他人称鳞,則同意將A選舉為領(lǐng)頭哨兵涮较;
如果A發(fā)現(xiàn)有超過半數(shù)且超過quorum參數(shù)值的哨兵節(jié)點(diǎn)同意選自己成為領(lǐng)頭哨兵稠鼻,則A哨兵成功選舉為領(lǐng)頭哨兵冈止。
【sentinel集群執(zhí)行故障轉(zhuǎn)移時(shí)需要選舉leader,此時(shí)涉及到majority候齿,majority 代表 sentinel 集群中大部分 sentinel 節(jié)點(diǎn)的個(gè)數(shù)熙暴,只有大于等于 max(quorum, majority) 個(gè)節(jié)點(diǎn)給某個(gè) sentinel 節(jié)點(diǎn)投票,才能確定該sentinel節(jié)點(diǎn)為leader慌盯,majority 的計(jì)算方式為:num(sentinels) / 2 + 1】
當(dāng)有多個(gè)哨兵節(jié)點(diǎn)同時(shí)參與領(lǐng)頭哨兵選舉時(shí)周霉,出現(xiàn)沒有任何節(jié)點(diǎn)當(dāng)選可能,此時(shí)每個(gè)參選節(jié)點(diǎn)等待一個(gè)隨機(jī)時(shí)間進(jìn)行下一輪選舉亚皂,直到選出領(lǐng)頭哨兵俱箱。
??故障恢復(fù)時(shí)從Slave中間選出Master的算法
按照slave優(yōu)先級(jí)進(jìn)行排序,slave-priority越低灭必,優(yōu)先級(jí)就越高狞谱;
如果slave priority相同,那么比較復(fù)制偏移量禁漓,offset越靠后(越大)則表明和舊的主庫數(shù)據(jù)同步越接近跟衅,優(yōu)先級(jí)就越高 ;
如果上面兩個(gè)條件都相同播歼,那么選擇一個(gè)run id最小的從庫伶跷;
主要根據(jù)slave-priority進(jìn)行排序做控制選舉,先比較slave_offset值越大優(yōu)先級(jí)越高秘狞,如果相等在獲取runid最小的(代表啟動(dòng)時(shí)間越早)叭莫。
??Sentinel(哨兵)的運(yùn)作流程
每個(gè)Sentinel以每秒鐘一次的頻率向它所知的Master辩恼,Slave以及其他 Sentinel 實(shí)例發(fā)送一個(gè) PING 命令赴精。(心跳機(jī)制)
如果一個(gè)實(shí)例(instance)距離最后一次有效回復(fù) PING 命令的時(shí)間超過 down-after-milliseconds 選項(xiàng)所指定的值, 則這個(gè)實(shí)例會(huì)被 Sentinel 標(biāo)記為主觀下線烛恤。
如果一個(gè)Master被標(biāo)記為主觀下線廓潜,則正在監(jiān)視這個(gè)Master的所有 Sentinel 要以每秒一次的頻率確認(rèn)Master的確進(jìn)入了主觀下線狀態(tài)抵皱。(確認(rèn)投票下線)
當(dāng)有足夠數(shù)量的 Sentinel(大于等于配置文件指定的值)在指定的時(shí)間范圍內(nèi)確認(rèn)Master的確進(jìn)入了主觀下線狀態(tài), 則Master會(huì)被標(biāo)記為客觀下線 辩蛋。
在一般情況下呻畸, 每個(gè) Sentinel 會(huì)以每 10 秒一次的頻率向它已知的所有Master,Slave發(fā)送 INFO 命令悼院。(同步數(shù)據(jù))
當(dāng)Master被 Sentinel 標(biāo)記為客觀下線時(shí)伤为,Sentinel 向下線的 Master 的所有 Slave 發(fā)送 INFO 命令的頻率會(huì)從 10 秒一次改為每秒一次。
若沒有足夠數(shù)量的 Sentinel 同意 Master 已經(jīng)下線, Master 的客觀下線狀態(tài)就會(huì)被移除绞愚。
若 Master 重新向 Sentinel 的 PING 命令返回有效回復(fù)叙甸, Master 的主觀下線狀態(tài)就會(huì)被移除。
??Sentinel部署配置
redis源碼中提供了 sentinel 配置的模板:sentinel.conf
Sentinel部署很簡單位衩,只需要配置一下/etc/redis-sentinel.conf配置文件就可以了裆蒸,如下
#工作端口
port 26379
#工作目錄
dir "/var/lib/redis/sentinel"
#sentinel id ,建議注釋掉糖驴,會(huì)自動(dòng)生成
#sentinel myid 827f0104ad153f34db5a29b8cbb51ef21a31d6d5
#配置要監(jiān)控的master名字和地址僚祷,最后一個(gè)2代表當(dāng)sentinel集群中有2個(gè)sentinel認(rèn)為master故障時(shí)候才判定master真正不可用。
官方把該參數(shù)稱為quorum贮缕,在后續(xù)選舉領(lǐng)頭哨兵時(shí)候會(huì)用到
sentinel monitor mymaster 10.130.2.155 6379 2
#配置master密碼:配置主服務(wù)器的密碼(如沒設(shè)置密碼辙谜,可以省略)
sentinel auth-pass mymaster Password
#日志
logfile "/var/log/redis/sentinel.log"
配置完成后,使用systemctl start redis-sentinel啟動(dòng)即可感昼。
Sentinel可以調(diào)整的相關(guān)參數(shù)
#主觀SDOWN時(shí)間装哆,單位毫秒,默認(rèn)30秒定嗓。(心跳檢測)
sentinel down-after-milliseconds mymaster 30000
#在發(fā)生failover主備切換時(shí)候蜕琴,最多允許多少個(gè)slave同時(shí)同步新的master。這個(gè)數(shù)字越小蜕乡,完成failover所需的時(shí)間就越長奸绷,但是如果這個(gè)數(shù)字越大,就意味著越多的slave因?yàn)閞eplication而不可用层玲『抛恚可以通過將這個(gè)值設(shè)為 1 來保證每次只有一個(gè)slave處于不能處理命令請(qǐng)求的狀態(tài)。
sentinel parallel-syncs mymaster 1
#failover-time超時(shí)時(shí)間辛块,當(dāng)failover開始后畔派,在此時(shí)間內(nèi)仍然沒有觸發(fā)任何failover操作,當(dāng)前sentinel將會(huì)認(rèn)為此次failover失敗润绵,單位毫秒线椰。默認(rèn)3分鐘。
sentinel failover-timeout mymaster 180000
??核心配置
sentinel monitor <master-name> <ip> <redis-port> <quorum>: 監(jiān)控的 redis 主節(jié)點(diǎn)
#配置主服務(wù)器的密碼(如沒設(shè)置密碼尘盼,可以省略)
sentinel auth-pass mymaster 123456
#修改心跳檢測 5000毫秒
sentinel down-after-milliseconds mymaster 5000
- sentinel 是 redis 配置的提供者憨愉,而不是代理,客戶端只是從 sentinel 獲取數(shù)據(jù)節(jié)點(diǎn)的配置卿捎,因此這里的 ip 必須是 redis 客戶端能夠訪問的配紫。
??Sentinel 啟動(dòng)
雖然哨兵(sentinel) 釋出為一個(gè)單獨(dú)的可執(zhí)行文件 redis-sentinel ,但實(shí)際上它只是一個(gè)運(yùn)行在特殊模式下的 Redis 服務(wù)器,你可以在啟動(dòng)一個(gè)普通 Redis 服務(wù)器時(shí)通過給定 --sentinel 選項(xiàng)來啟動(dòng)哨兵(sentinel)午阵。
如果你使用redis-sentinel可執(zhí)行文件躺孝,你可以使用下面的命令來運(yùn)行Sentinel:
$ redis-sentinel /path/to/sentinel.conf
當(dāng)然也可以采用 redis服務(wù)的方式啟動(dòng):
$ redis-server sentinel.conf --sentinel &
兩種方式是一樣的。
不管咋樣,使用一個(gè)配置文件來運(yùn)行Sentinel是必須的植袍,這個(gè)文件被系統(tǒng)使用來存儲(chǔ)當(dāng)前狀態(tài)惧眠,如果重啟,這些狀態(tài)會(huì)被重新載入于个。如果沒有配置文件或者配置文件的路徑不對(duì)氛魁,Sentinel將會(huì)拒絕啟動(dòng)。
默認(rèn)情況下览濒,Sentinels監(jiān)聽TCP端口26379呆盖,所以為了讓Sentinels運(yùn)行拖云,你的機(jī)器的26379端口必須是打開的贷笛,用來接收其他Sentinel實(shí)例的連接,否則宙项,Sentinels不能互相交流乏苦,也不知道該干什么,也不會(huì)執(zhí)行故障轉(zhuǎn)移尤筐。
初始化一個(gè)普通的redis服務(wù)器
加載Sentinel專用配置汇荐,例如命令表、參數(shù)等盆繁,Sentinel 使用 sentinel.c 中的命令表掀淘、函數(shù)等配置,普通 Redis 則使用 redis.c 中的配置
除了保存服務(wù)器一般狀態(tài)之外油昂,Sentinel 還會(huì)保存 Sentinel 相關(guān)狀態(tài)
注意:
1 .當(dāng)啟動(dòng)哨兵模式之后革娄,如果你的master服務(wù)器宕機(jī)之后,哨兵自動(dòng)會(huì)在從redis服務(wù)器里面 投票選舉一個(gè)master主服務(wù)器出來冕碟;這個(gè)主服務(wù)器也可以進(jìn)行讀寫操作拦惋!
如果之前宕機(jī)的主服務(wù)器已經(jīng)修好,可以正式運(yùn)行了安寺。那么這個(gè)服務(wù)器只能進(jìn)行讀的操作厕妖,會(huì)自動(dòng)跟隨由哨兵選舉出來的新服務(wù)器!
大家可以進(jìn)入./redis-cli挑庶,輸入info言秸,查看你的狀態(tài)信息;
??Redis截止到現(xiàn)在仍存在的問題
[哨兵已解決] :一旦主節(jié)點(diǎn)宕機(jī)迎捺,從節(jié)點(diǎn)晉升成主節(jié)點(diǎn)举畸,同時(shí)需要修改應(yīng)用方的主節(jié)點(diǎn)地址,還需要命令所有從節(jié)點(diǎn)去復(fù)制新的主節(jié)點(diǎn)破加,整個(gè)過程需要人工干預(yù)俱恶。
[集群已解決] :節(jié)點(diǎn)的寫能力受到單機(jī)的限制。
[集群已解決] :節(jié)點(diǎn)的存儲(chǔ)能力受到單機(jī)的限制。