如果你用redis緩存技術(shù)的話(huà),肯定要考慮如何用redis來(lái)加多臺(tái)機(jī)器投蝉,保證redis是高并發(fā)的养葵,還有就是如何讓Redis保證自己不是掛掉以后就直接死掉了,redis高可用
redis高并發(fā):主從架構(gòu)瘩缆,一主多從关拒,一般來(lái)說(shuō),很多項(xiàng)目其實(shí)就足夠了咳榜,單主用來(lái)寫(xiě)入數(shù)據(jù)夏醉,單機(jī)幾萬(wàn)QPS,多從用來(lái)查詢(xún)數(shù)據(jù)涌韩,多個(gè)從實(shí)例可以提供每秒10萬(wàn)的QPS畔柔。
redis高并發(fā)的同時(shí),還需要容納大量的數(shù)據(jù):一主多從臣樱,每個(gè)實(shí)例都容納了完整的數(shù)據(jù)靶擦,比如redis主就10G的內(nèi)存量,其實(shí)你就最對(duì)只能容納10g的數(shù)據(jù)量雇毫。如果你的緩存要容納的數(shù)據(jù)量很大玄捕,達(dá)到了幾十g,甚至幾百g棚放,或者是幾t枚粘,那你就需要redis集群,而且用redis集群之后飘蚯,可以提供可能每秒幾十萬(wàn)的讀寫(xiě)并發(fā)馍迄。
redis高可用:如果你做主從架構(gòu)部署,其實(shí)就是加上哨兵就可以了局骤,就可以實(shí)現(xiàn)攀圈,任何一個(gè)實(shí)例宕機(jī),自動(dòng)會(huì)進(jìn)行主備切換峦甩。
下面詳細(xì)介紹
一.redis如何通過(guò)讀寫(xiě)分離來(lái)承載讀請(qǐng)求QPS超過(guò)10萬(wàn)+赘来?
1.redis高并發(fā)跟整個(gè)系統(tǒng)高并發(fā)的關(guān)系
redis要搞高并發(fā),那就要把底層的緩存搞好凯傲,讓更少的請(qǐng)求直接到數(shù)據(jù)庫(kù)犬辰,因?yàn)閿?shù)據(jù)庫(kù)的高并發(fā)實(shí)現(xiàn)起來(lái)是比較麻煩的,而且有些操作還有事務(wù)的要求等等冰单,所以很難做到非常高的并發(fā)忧风。
redis并發(fā)做的好對(duì)于整個(gè)系統(tǒng)的并發(fā)來(lái)說(shuō)還是不夠的,但是redis作為整個(gè)大型的緩存架構(gòu)球凰,在支撐高并發(fā)的架構(gòu)里面是非常重要的一環(huán)狮腿。
要實(shí)現(xiàn)系統(tǒng)的高并發(fā)腿宰,首先緩存中間件、緩存系統(tǒng)必須要能夠支撐起高并發(fā)缘厢,然后在經(jīng)過(guò)良好的整體緩存架構(gòu)設(shè)計(jì)(多級(jí)緩存吃度、熱點(diǎn)緩存),才能真正支撐起高并發(fā)。
2.redis不能支撐高并發(fā)的瓶頸
redis不能支撐高并發(fā)的瓶頸主要是單機(jī)問(wèn)題贴硫,也就是說(shuō)只有一個(gè)單一的redis椿每,就算機(jī)器性能再怎么好,也是有上限的英遭。
3.如何支撐更高的并發(fā)
單機(jī)的redis不可能支撐太高的并發(fā)量间护,要想支持更高的并發(fā)可以進(jìn)行 讀寫(xiě)分離 。對(duì)于緩存來(lái)說(shuō)挖诸,一般都是支撐讀高并發(fā)的汁尺,寫(xiě)的請(qǐng)求是比較少的,因此可以基于主從架構(gòu)進(jìn)行讀寫(xiě)分離多律。
配置一個(gè)master(主)機(jī)器用來(lái)寫(xiě)入數(shù)據(jù)痴突,配置多個(gè)slave(從)來(lái)進(jìn)行數(shù)據(jù)的讀取,在master接收到數(shù)據(jù)之后將數(shù)據(jù)同步到slave上面即可狼荞,這樣slave可以配置多臺(tái)機(jī)器辽装,就可以提高整體的并發(fā)量。
二.redis replication以及master持久化對(duì)主從架構(gòu)的安全意義
1.redis replication原理相味。
一個(gè)master節(jié)點(diǎn)下面掛若干個(gè)slave節(jié)點(diǎn)拾积,寫(xiě)操作將數(shù)據(jù)寫(xiě)到master節(jié)點(diǎn)上面去,然后在master寫(xiě)完之后丰涉,通過(guò)異步操作的方式將數(shù)據(jù)同步到所有的slave節(jié)點(diǎn)上面去殷勘,保證所有節(jié)點(diǎn)的數(shù)據(jù)是一致的。
2.redis replication的核心機(jī)制
(1)redis采用異步方式復(fù)制數(shù)據(jù)到slave節(jié)點(diǎn)昔搂,不過(guò)redis2.8開(kāi)始,slave node會(huì)周期性地確認(rèn)自己每次復(fù)制的數(shù)量输拇。
(2)一個(gè)master node 可以配置多個(gè) salve node摘符。
(3)slave node也可以連接其他的slave node。
(4)slave node做復(fù)制分時(shí)候策吠,是不會(huì)阻塞master node的正常工作的逛裤。
(5)slave node在做復(fù)制的時(shí)候,也不會(huì)阻塞自己的操作猴抹,它會(huì)用舊的數(shù)據(jù)來(lái)提供服務(wù)带族;但是復(fù)制完成的時(shí)候,需要?jiǎng)h除舊的數(shù)據(jù)蟀给,加載新的數(shù)據(jù)蝙砌,這個(gè)時(shí)候會(huì)對(duì)外暫停提供服務(wù)阳堕。
(6)slave node主要用來(lái)進(jìn)行橫向擴(kuò)容,做讀寫(xiě)分離择克,擴(kuò)容的slave node 可以提高吞吐量恬总。
3.master持久化對(duì)主從架構(gòu)的安全意義
如果采用這種主從架構(gòu),那么必須要開(kāi)啟master node的持久化肚邢。不建議使用slave node作為master node的熱備份壹堰,因?yàn)槿绻@樣的話(huà),如果master一旦宕機(jī)骡湖,那么master的數(shù)據(jù)就會(huì)丟失贱纠,重啟之后數(shù)據(jù)是空的,其他的slave node要是來(lái)復(fù)制數(shù)據(jù)的話(huà)响蕴,就會(huì)復(fù)制到空谆焊,這樣所有節(jié)點(diǎn)的數(shù)據(jù)就都丟了。
要對(duì)備份文件做多種冷備份换途,防止整個(gè)機(jī)器壞了懊渡,備份的rdb數(shù)據(jù)也丟失的情況。
三.redis主從復(fù)制原理军拟、斷點(diǎn)續(xù)傳剃执、無(wú)磁盤(pán)化復(fù)制、過(guò)期key處理
1.主從復(fù)制原理
①當(dāng)啟動(dòng)一個(gè)slave node的時(shí)候懈息,它會(huì)發(fā)送一個(gè)PSYNC 命令給master node肾档。
②如果這個(gè)slave node是重新連接master node,那么master node 僅僅會(huì)復(fù)制給slave部分缺失的數(shù)據(jù)辫继;如果是第一次連接master node怒见,那么就會(huì)觸發(fā)一次 full resynchronization。
③開(kāi)始 full resynchronization的時(shí)候姑宽,master會(huì)啟動(dòng)一個(gè)后臺(tái)線(xiàn)程 遣耍,開(kāi)始生成一份RDB快照文件,同時(shí)還會(huì)將從客戶(hù)端新接收到的所有寫(xiě)命令緩存在內(nèi)存當(dāng)中炮车。
④master node將生成的RDB文件發(fā)送給slave node舵变,slave現(xiàn)將其寫(xiě)入本地磁盤(pán),然后再?gòu)拇疟P(pán)加載到內(nèi)存當(dāng)中瘦穆。然后master node會(huì)將內(nèi)存中緩存的寫(xiě)命令發(fā)送給slave node纪隙,slave node也會(huì)同步這部分?jǐn)?shù)據(jù) 。
⑤slave node如果跟master node因?yàn)榫W(wǎng)絡(luò)故障斷開(kāi)了連接扛或,會(huì)自動(dòng)重連 绵咱。
⑥master如果發(fā)現(xiàn)有多個(gè)slave node來(lái)重新連接,僅僅會(huì)啟動(dòng)一個(gè)rdb save操作 熙兔,用一份數(shù)據(jù)服務(wù)所有slave node悲伶。
2.主從復(fù)制的斷點(diǎn)續(xù)傳
從redis2.8開(kāi)始支持?jǐn)帱c(diǎn)續(xù)傳艾恼。如果在主從復(fù)制的過(guò)程中,網(wǎng)絡(luò)突然斷掉了拢切,那么可以接著上次
復(fù)制的地方蒂萎,繼續(xù)復(fù)制,而不是從頭復(fù)制一份淮椰。
原理:
master node會(huì)在內(nèi)存中創(chuàng)建一個(gè)backlog五慈,master和slave都會(huì)保存一個(gè)replica offset還有一個(gè)master id水泉,offset就保存在backlog中辰如。如果master和slave網(wǎng)絡(luò)連接斷掉了唬涧,slave會(huì)讓master從上次的replica offset開(kāi)始繼續(xù)復(fù)制土至。但是如果沒(méi)有找到offset样刷,就會(huì)執(zhí)行一次 full resynchronization操作注竿。
3.無(wú)磁盤(pán)化復(fù)制
無(wú)磁盤(pán)化復(fù)制是指粮坞,master直接再內(nèi)存中創(chuàng)建RDB文件蝗岖,然后發(fā)送給slave晦雨,不會(huì)在自己本地磁盤(pán)保存數(shù)據(jù)架曹。
設(shè)置方式
配置 repl-diskless-sync和repl-diskless-sync-delay參數(shù)。
repl-diskless-sync:該參數(shù)保證進(jìn)行無(wú)磁盤(pán)化復(fù)制闹瞧。
repl-diskless-sync-delay:該參數(shù)表示等待一定時(shí)長(zhǎng)再開(kāi)始復(fù)制绑雄,這樣可以等待多個(gè)slave節(jié)點(diǎn)從新連接上來(lái)。
4.過(guò)期key處理
slave不會(huì)過(guò)期key 奥邮,只有等待master過(guò)期key万牺。
如果master過(guò)期了一個(gè)key,或者淘汰了一個(gè)key洽腺,那么master會(huì)模擬發(fā)送一條del命令 給slave脚粟,slave接到之后會(huì)刪除該key。
四.redis replication的完整流運(yùn)行程和原理的再次深入剖析
1.復(fù)制的完整流程
①slave node啟動(dòng)蘸朋,僅僅保存了master node的信息核无,包括master node的host和ip,但是數(shù)據(jù)復(fù)制還沒(méi)有開(kāi)始藕坯。 master node的host和ip是在redis.conf文件里面的slaveOf中配置的 团南。
②slave node內(nèi)部有一個(gè)定時(shí)任務(wù),每秒檢查是否有新的master node要連接個(gè)復(fù)制堕担,如果發(fā)現(xiàn),就跟master node建立socket網(wǎng)絡(luò)連接曲聂。
③slave node發(fā)送ping命令給master node霹购。
④如果master設(shè)置了requirepass,那么slave node必須發(fā)送master auth的口令過(guò)去進(jìn)行口令驗(yàn)證朋腋。
⑤master node第一次執(zhí)行全量復(fù)制齐疙,將所有數(shù)據(jù)發(fā)送給slave node膜楷。
⑥master node持續(xù)降寫(xiě)命令,異步復(fù)制給slave node贞奋。
2.數(shù)據(jù)同步的機(jī)制
指的是slave第一次連接master時(shí)的情況赌厅,執(zhí)行的是全量復(fù)制。
①master和slave都會(huì)維護(hù)一個(gè)offset
master會(huì)在自身不斷累加offset轿塔,slave也會(huì)在自身不斷累加offset特愿。slave每秒都會(huì)上報(bào)自己的offset給master,同時(shí)master也會(huì)保存每個(gè)slave的offset勾缭。
這個(gè)倒不是說(shuō)特定就用在全量復(fù)制的揍障,主要是master和slave都要知道各自的數(shù)據(jù)的offset,才能知道互相之間的數(shù)據(jù)不一致的情況
②backlog
master node有一個(gè)backlog在內(nèi)存中俩由,默認(rèn)是1M大毒嫡。
master node給slave node復(fù)制數(shù)據(jù)時(shí),也會(huì)將數(shù)據(jù)在backlog中同步一份幻梯。
backlog主要是用來(lái)做全量復(fù)制中斷時(shí)候的增量復(fù)制的兜畸。
③master run id
redis通過(guò)info server 可以查看到master run id。
用途:slave根據(jù)其來(lái)定位唯一的master碘梢。
為什么不用host+ip : 因?yàn)槭褂胔ost+ip來(lái)定位master是不靠譜的咬摇,如果master node重啟或者數(shù)據(jù)出現(xiàn)了變化,那么slave應(yīng)該根據(jù)不同的master run id進(jìn)行區(qū)分痘系,run id不同就需要做一次全量復(fù)制菲嘴。
如果需要不更改run id重啟redis,可以使用redis-cli debug reload 命令汰翠。
3.全量復(fù)制流程與機(jī)制
①master執(zhí)行bgsave龄坪,在本地生成一份RDB文件。
②master node將RDB快照文件發(fā)送給slave node复唤,如果RDB文件的復(fù)制時(shí)間超過(guò)60秒(repl-timeout),那么slave node就會(huì)任務(wù)復(fù)制失敗健田,可以適當(dāng)調(diào)整這個(gè)參數(shù)。
③對(duì)于千兆網(wǎng)卡的機(jī)器佛纫,一般每秒傳輸100M妓局,傳輸6G文件很可能超過(guò)60秒。
④master node在生成RDB文件時(shí)呈宇,會(huì)將所有新接到的寫(xiě)命令緩存在內(nèi)存中好爬,在slave node保存了RDB文件之后,再將這些寫(xiě)命令復(fù)制個(gè)slave node甥啄。
⑤查看client-output-buffer-limit slave 參數(shù)存炮,比如[client-output-buffer-limit slave 256MB 64MB 60],表示在復(fù)制期間,內(nèi)存緩存去持續(xù)消耗超過(guò)64M,或者一次性超過(guò)256MB穆桂,那么停止復(fù)制宫盔,復(fù)制失敗。
⑥slave node接收到RDB文件之后享完,清空自己的數(shù)據(jù)灼芭,然后重新加載RDB文件到自己的內(nèi)存中,在這個(gè)過(guò)程中般又,基于舊數(shù)據(jù)對(duì)外提供服務(wù)彼绷。
⑦如果slave node開(kāi)啟了AOF,那么會(huì)立即執(zhí)行BRREWRITEAOF倒源,重新AOF
rdb生成苛预、rdb通過(guò)網(wǎng)絡(luò)拷貝、slave舊數(shù)據(jù)的清理笋熬、slave aof rewrite热某,很耗費(fèi)時(shí)間
如果復(fù)制的數(shù)據(jù)量在4G~6G之間,那么很可能全量復(fù)制時(shí)間消耗到1分半到2分鐘
4.增量復(fù)制流程與機(jī)制
①如果全量復(fù)制過(guò)程中胳螟,master和slave網(wǎng)絡(luò)連接斷掉昔馋,那么slave重新連接master會(huì)觸發(fā)增刊復(fù)制。
②master直接從自己的backlog中獲取部分丟失是數(shù)據(jù)糖耸,發(fā)送給slave node秘遏。
③master就是根據(jù)slave發(fā)送的psync中的offset來(lái)從backlog中獲取數(shù)據(jù)的。
5.心跳
master和slave互相都會(huì)發(fā)送heartbeat信息嘉竟。
master默認(rèn)每隔10秒發(fā)送一次邦危,slave node默認(rèn)每隔1秒發(fā)送一次。
6.異步復(fù)制
master每次接收到寫(xiě)命令之后舍扰,現(xiàn)在內(nèi)部寫(xiě)入數(shù)據(jù)倦蚪,然后異步發(fā)送給slave node
五.redis主從架構(gòu)下如何才能做到99.99%的高可用性?
1.什么是99.99%高可用?
高可用性(英語(yǔ):high availability边苹,縮寫(xiě)為 HA)陵且,IT術(shù)語(yǔ),指系統(tǒng)無(wú)中斷地執(zhí)行其功能的能力个束,代表系統(tǒng)的可用性程度慕购。是進(jìn)行系統(tǒng)設(shè)計(jì)時(shí)的準(zhǔn)則之一。高可用性系統(tǒng)與構(gòu)成該系統(tǒng)的各個(gè)組件相比可以更長(zhǎng)時(shí)間運(yùn)行茬底。
高可用性通常通過(guò)提高系統(tǒng)的容錯(cuò)能力來(lái)實(shí)現(xiàn)沪悲。定義一個(gè)系統(tǒng)怎樣才算具有高可用性往往需要根據(jù)每一個(gè)案例的具體情況來(lái)具體分析。
其度量方式阱表,是根據(jù)系統(tǒng)損害殿如、無(wú)法使用的時(shí)間昌妹,以及由無(wú)法運(yùn)作恢復(fù)到可運(yùn)作狀況的時(shí)間,與系統(tǒng)總運(yùn)作時(shí)間的比較握截。計(jì)算公式為:image.png
A(可用性),MTBF(平均故障間隔)烂叔,MDT(平均修復(fù)時(shí)間)
在線(xiàn)系統(tǒng)和執(zhí)行關(guān)鍵任務(wù)的系統(tǒng)通常要求其可用性要達(dá)到5個(gè)9標(biāo)準(zhǔn)(99.999%)谨胞。
可用性 | 年故障時(shí)間 |
---|---|
99.9999% | 32秒 |
99.999% | 5分15秒 |
99.99% | 52分34秒 |
99.9% | 8小時(shí)46分 |
99% | 3天15小時(shí)36分 |
2.redis不可用
redis不可以包含了單實(shí)例的不可用,主從架構(gòu)的不可用蒜鸡。
不可用的情況:
①主從架構(gòu)的master節(jié)點(diǎn)掛了胯努,如果master節(jié)點(diǎn)掛了那么緩存數(shù)據(jù)無(wú)法再寫(xiě)入,而且slave里面的數(shù)據(jù)也無(wú)法過(guò)期逢防,這樣就導(dǎo)致了不可用叶沛。
②如果是單實(shí)例,那么可能因?yàn)槠渌驅(qū)е聄edis進(jìn)程死了忘朝』沂穑或者部署redis的機(jī)器壞了。
不可用的后果 :首先緩存不可用了局嘁,那么請(qǐng)求就會(huì)直接走數(shù)據(jù)庫(kù)溉箕,如果涌入大量請(qǐng)求超過(guò)了數(shù)據(jù)庫(kù)的承載能力,那么數(shù)據(jù)庫(kù)就掛掉了悦昵,這時(shí)候如果不能及時(shí)處理好緩存問(wèn)題肴茄,那么由于請(qǐng)求過(guò)多,數(shù)據(jù)庫(kù)重啟之后很快就又會(huì)掛掉但指,直接導(dǎo)致整個(gè)系統(tǒng)不可用寡痰。
3.如何實(shí)現(xiàn)高可用
①保證每個(gè)redis都有備份。
②保證在當(dāng)前redis出故障之后棋凳,可以很快切換到備份redis上面去拦坠。
為了解決這個(gè)問(wèn)題,引入下面的哨兵機(jī)制贫橙。
六.redis哨兵架構(gòu)的相關(guān)基礎(chǔ)知識(shí)的講解
1.什么是哨兵贪婉?
哨兵(Sentinal)是redis集群架構(gòu)當(dāng)中非常重要的一個(gè)組件,它主要有一下功能:
①集群監(jiān)控 卢肃,負(fù)責(zé)監(jiān)控redis master和slave進(jìn)程是否正常工作疲迂。
②消息通知 ,如果某個(gè)redis實(shí)例有故障莫湘,那么哨兵負(fù)責(zé)發(fā)送消息作為報(bào)警通知給管理員尤蒿。
③故障轉(zhuǎn)移 ,如果master掛掉了幅垮,會(huì)自動(dòng)轉(zhuǎn)移到slave上腰池。
④配置中心 ,如果故障發(fā)生了,通知client客戶(hù)端連接到新的master上面去示弓。
2.哨兵的核心知識(shí)
①哨兵本身是分布式的讳侨,需要作為一個(gè)集群去運(yùn)行,個(gè)哨兵協(xié)同工作奏属。
②故障轉(zhuǎn)移時(shí)跨跨,判斷一個(gè)master宕機(jī)了,需要大部分哨兵同意才行囱皿。
③即使部分哨兵掛掉了勇婴,哨兵集群還是能正常工作的。
④哨兵至少需要3個(gè)實(shí)例嘱腥,來(lái)保證自己的健壯性耕渴。
⑤哨兵+redis主從結(jié)構(gòu),是無(wú)法保證數(shù)據(jù)零丟失的齿兔,只會(huì)保證redis集群的高可用橱脸。
⑥對(duì)應(yīng)哨兵+redis主從這種架構(gòu),再使用之前分苇,要做重復(fù)的測(cè)試和演練慰技。
3.為什么哨兵集群部署2個(gè)節(jié)點(diǎn)無(wú)法正常工作?
哨兵集群必須部署2個(gè)以上的節(jié)點(diǎn)组砚。如果集群僅僅部署了2個(gè)哨兵實(shí)例吻商,那么quorum=1(執(zhí)行故障轉(zhuǎn)移需要同意的哨兵個(gè)數(shù))。
如圖糟红,如果這時(shí)候master1宕機(jī)了艾帐,哨兵1和哨兵2中只要有一個(gè)認(rèn)為master1宕機(jī)了就可以進(jìn)行故障轉(zhuǎn)移,同時(shí)哨兵1和哨兵2會(huì)選舉出一個(gè)哨兵來(lái)執(zhí)行故障轉(zhuǎn)移盆偿。
同時(shí)這個(gè)時(shí)候需要majority(也就是所有集群中超過(guò)一半哨兵的數(shù)量)柒爸,2個(gè)哨兵那么majority就是2,也就說(shuō)需要至少2個(gè)哨兵還運(yùn)行著事扭,才可以進(jìn)行故障轉(zhuǎn)移捎稚。
但是如果整個(gè)master和哨兵1同時(shí)宕機(jī)了,那么就只剩一個(gè)哨兵了求橄,這個(gè)時(shí)候就沒(méi)有majority來(lái)運(yùn)行執(zhí)行故障轉(zhuǎn)移了今野,雖然兩外一臺(tái)機(jī)器還有一個(gè)哨兵,但是1無(wú)法大于1罐农,也就是無(wú)法保證半數(shù)以上条霜,因此故障轉(zhuǎn)移不會(huì)執(zhí)行。
4.經(jīng)典的3節(jié)點(diǎn)哨兵集群
Configuration: quorum = 2涵亏,majority=2
如果M1所在機(jī)器宕機(jī)了宰睡,那么三個(gè)哨兵還剩下2個(gè)蒲凶,S2和S3可以一致認(rèn)為master宕機(jī),然后選舉出一個(gè)來(lái)執(zhí)行故障轉(zhuǎn)移
同時(shí)3個(gè)哨兵的majority是2拆内,所以還剩下的2個(gè)哨兵運(yùn)行著旋圆,就可以允許執(zhí)行故障轉(zhuǎn)移
七.redis哨兵主備切換的數(shù)據(jù)丟失問(wèn)題:異步復(fù)制、集群腦裂
1.兩種數(shù)據(jù)丟失的場(chǎng)景
①異步復(fù)制導(dǎo)致的數(shù)據(jù)丟失
因?yàn)閺膍aster到slave的數(shù)據(jù)復(fù)制過(guò)程是異步的麸恍,可能有部分?jǐn)?shù)據(jù)還沒(méi)來(lái)得及復(fù)制到slave上面去臂聋,這時(shí)候master就宕機(jī)了,那么這部分?jǐn)?shù)據(jù)就丟失了或南。
②集群腦裂導(dǎo)致的數(shù)據(jù)丟失
什么是腦裂:腦裂,也就是說(shuō)艾君,某個(gè)master所在機(jī)器突然脫離了正常的網(wǎng)絡(luò)采够,跟其他slave機(jī)器不能連接,但是實(shí)際上master還運(yùn)行著冰垄。
此時(shí)哨兵可能就會(huì)認(rèn)為master宕機(jī)了蹬癌,然后開(kāi)啟選舉,將其他slave切換成了master虹茶。
這個(gè)時(shí)候逝薪,集群里就會(huì)有兩個(gè)master,也就是所謂的腦裂蝴罪。
此時(shí)雖然某個(gè)slave被切換成了master董济,但是可能client還沒(méi)來(lái)得及切換到新的master,還繼續(xù)寫(xiě)向舊master的數(shù)據(jù)可能也丟失了要门。
因此舊master再次恢復(fù)的時(shí)候虏肾,會(huì)被作為一個(gè)slave掛到新的master上去,自己的數(shù)據(jù)會(huì)清空欢搜,重新從新的master復(fù)制數(shù)據(jù)
2.解決異步復(fù)制的腦裂導(dǎo)致的數(shù)據(jù)丟失
要解決這個(gè)問(wèn)題封豪,就需要配置兩個(gè)參數(shù):
min-slaves-to-write 1 和 min-slaves-max-lag :
表示 要求至少有一個(gè)slave 在進(jìn)行數(shù)據(jù)的復(fù)制和同步的延遲不能超過(guò)10秒。
如果一旦所有的slave數(shù)據(jù)同步和復(fù)制的延遲都超過(guò)了10秒炒瘟,那么這個(gè)時(shí)候吹埠,master就會(huì)在接受任何請(qǐng)求了。
①減少異步復(fù)制的數(shù)據(jù)丟失
有了min-slaves-max-lag這個(gè)配置疮装,就可以確保說(shuō)缘琅,一旦slave復(fù)制數(shù)據(jù)和ack延時(shí)太長(zhǎng),就認(rèn)為可能master宕機(jī)后損失的數(shù)據(jù)太多了廓推,那么就拒絕寫(xiě)請(qǐng)求胯杭,這樣可以把master宕機(jī)時(shí)由于部分?jǐn)?shù)據(jù)未同步到slave導(dǎo)致的數(shù)據(jù)丟失降低的可控范圍內(nèi)。
(2)減少腦裂的數(shù)據(jù)丟失
如果一個(gè)master出現(xiàn)了腦裂受啥,跟其他slave丟了連接做个,那么上面兩個(gè)配置可以確保說(shuō)鸽心,如果不能繼續(xù)給指定數(shù)量的slave發(fā)送數(shù)據(jù),而且slave超過(guò)10秒沒(méi)有給自己ack消息居暖,那么就直接拒絕客戶(hù)端的寫(xiě)請(qǐng)求顽频。
這樣腦裂后的舊master就不會(huì)接受client的新數(shù)據(jù),也就避免了數(shù)據(jù)丟失太闺。
上面的配置就確保了糯景,如果跟任何一個(gè)slave丟了連接,在10秒后發(fā)現(xiàn)沒(méi)有slave給自己ack省骂,那么就拒絕新的寫(xiě)請(qǐng)求蟀淮。
因此在腦裂場(chǎng)景下,最多就丟失10秒的數(shù)據(jù)
八.redis哨兵的多個(gè)核心底層原理的深入解析(包含slave選舉算法)
1.sdown和odown兩種狀態(tài)
sdown是主觀(guān)宕機(jī)钞澳,就一個(gè)哨兵如果自己覺(jué)得一個(gè)master宕機(jī)了怠惶,那么就是主觀(guān)宕機(jī)
odown是客觀(guān)宕機(jī),如果quorum數(shù)量的哨兵都覺(jué)得一個(gè)master宕機(jī)了轧粟,那么就是客觀(guān)宕機(jī)
sdown達(dá)成的條件很簡(jiǎn)單策治,如果一個(gè)哨兵ping一個(gè)master,超過(guò)了is-master-down-after-milliseconds指定的毫秒數(shù)之后兰吟,就主觀(guān)認(rèn)為master宕機(jī)
sdown到odown轉(zhuǎn)換的條件很簡(jiǎn)單通惫,如果一個(gè)哨兵在指定時(shí)間內(nèi),收到了quorum指定數(shù)量的其他哨兵也認(rèn)為那個(gè)master是sdown了混蔼,那么就認(rèn)為是odown了履腋,客觀(guān)認(rèn)為master宕機(jī)。
2.哨兵集群的字段發(fā)現(xiàn)機(jī)制
①哨兵相互之間的發(fā)現(xiàn)惭嚣,是通過(guò)redis的pub/sub系統(tǒng)實(shí)現(xiàn)的府树,每個(gè)哨兵都會(huì)往 __sentinel__:hello 這個(gè)channel里面發(fā)送一個(gè)消息,這時(shí)候其他的哨兵都可以消費(fèi)這個(gè)消息料按,并感知其他哨兵的存在奄侠。
②每個(gè)兩秒鐘,每個(gè)哨兵都會(huì)往自己監(jiān)控的某個(gè)master+slave對(duì)應(yīng)的__sentinel__:hello channel里面發(fā)送一個(gè)消息载矿,內(nèi)容是自己的host垄潮、ip和run id還有對(duì)這個(gè)master的監(jiān)控配置。
③每個(gè)哨兵也會(huì)去監(jiān)聽(tīng)自己監(jiān)控的每個(gè)master+slave對(duì)應(yīng)的__sentinel__:hello channel闷盔,r然后去感知到同樣在監(jiān)聽(tīng)這個(gè)master+slave的其他哨兵的存在弯洗。
④每個(gè)哨兵還會(huì)根據(jù)其他哨兵交換對(duì)master的監(jiān)控配置,互相進(jìn)行監(jiān)控配置的同步逢勾。
3.slave配置的自我糾正
哨兵會(huì)負(fù)責(zé)自動(dòng)糾正slave的一些配置牡整,比如slave如果要成為潛在的master候選人,哨兵會(huì)確保slave在復(fù)制現(xiàn)有master數(shù)據(jù)溺拱;如果slave連接到了一個(gè)錯(cuò)誤的master上逃贝,比如故障轉(zhuǎn)移之后谣辞,那么哨兵會(huì)確保他們連接到正確的master上來(lái)。
4.選舉算法
如果一個(gè)master被認(rèn)為odown了沐扳,而且majority數(shù)量的哨兵都允許了主備切換泥从,那么某個(gè)哨兵就會(huì)執(zhí)行主備切換,此時(shí)首先要選舉一個(gè)slave出來(lái)沪摄。選舉會(huì)考慮到一下情況:
①slave跟master斷開(kāi)連接的時(shí)長(zhǎng)
②slave的優(yōu)先級(jí)
③slave復(fù)制數(shù)據(jù)的offset
④slave的run id
首先躯嫉,如果一個(gè)slave跟master斷開(kāi)連接已經(jīng)超過(guò)了 down-after-millisecondes 的10倍,外加master宕機(jī)的時(shí)長(zhǎng)杨拐,那么slave就被認(rèn)為不適合選舉為master了祈餐。
即:斷開(kāi)連接時(shí)間 > down-after-milliseconds * 10 + milliseconds_since_master_is_in_SDOWN_sate.
對(duì)應(yīng)剩下的slave按照如下規(guī)定排序:
①首先,按照slave的優(yōu)先級(jí)進(jìn)行排序哄陶,slave priority越低帆阳,優(yōu)先級(jí)就越高。
②如果優(yōu)先級(jí)相同奕筐,那么就看replica offset,那個(gè)slave復(fù)制了越多的數(shù)據(jù)变骡,offset越靠后离赫,優(yōu)先級(jí)就越高。
③如果上面都想同塌碌,那就選擇run id最小的那個(gè)slave渊胸。
5.quorum和majority
每次一個(gè)哨兵做主備切換,首先需要quorum數(shù)量的哨兵認(rèn)為odown台妆,然后選舉出一個(gè)哨兵來(lái)做主備切換翎猛,這個(gè)哨兵還要得到majority數(shù)量哨兵的授權(quán),才能正式執(zhí)行切換接剩。
如果quorum < majority ,比如5個(gè)哨兵切厘,majority就是3(超過(guò)半數(shù)),quorum設(shè)置為2懊缺,那么就需要3個(gè)哨兵授權(quán)就可以執(zhí)行切換疫稿。
如果 quorum >= majority,那么必須quorum數(shù)量的哨兵都授權(quán)才可以進(jìn)行切換鹃两,比如5個(gè)哨兵遗座,quorum是5,那么必須5個(gè)哨兵都同意授權(quán)俊扳,才可以進(jìn)行切換途蒋。
6.configuration epoch
哨兵會(huì)對(duì)一套redis master+slave進(jìn)行監(jiān)控,有相應(yīng)的監(jiān)控的配置馋记。
執(zhí)行切換的那個(gè)哨兵号坡,會(huì)從要切換到的新master(salve->master)那里得到一個(gè)configuration epoch懊烤,這就是一個(gè)version號(hào),每次切換的version號(hào)都必須是唯一的筋帖。
如果第一個(gè)選舉出的哨兵切換失敗了奸晴,那么其他哨兵,會(huì)等待failover-timeout時(shí)間日麸,然后接替繼續(xù)執(zhí)行切換寄啼,此時(shí)會(huì)重新獲取一個(gè)新的configuration epoch,作為新的version號(hào)代箭。
7墩划、configuraiton傳播
哨兵完成切換之后,會(huì)在自己本地更新生成最新的master配置嗡综,然后同步給其他的哨兵乙帮,就是通過(guò)之前說(shuō)的pub/sub消息機(jī)制。
這里之前的version號(hào)就很重要了极景,因?yàn)楦鞣N消息都是通過(guò)一個(gè)channel去發(fā)布和監(jiān)聽(tīng)的察净,所以一個(gè)哨兵完成一次新的切換之后,新的master配置是跟著新的version號(hào)的盼樟。
其他的哨兵都是根據(jù)版本號(hào)的大小來(lái)更新自己的master配置的氢卡。