1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        頭條二面:宕機(jī)后,Redis如何實(shí)現(xiàn)快速恢復(fù)?

        共 3647字,需瀏覽 8分鐘

         ·

        2020-12-23 07:19

        這篇文章,我們來(lái)看Redis是如何實(shí)現(xiàn)故障自動(dòng)恢復(fù)的,它的實(shí)現(xiàn)正是要基于之前所講的數(shù)據(jù)持久化和數(shù)據(jù)多副本而做的。

        Redis作為非?;馃岬膬?nèi)存數(shù)據(jù)庫(kù),其除了具有非常高的性能之外,還需要保證高可用,在故障發(fā)生時(shí),盡可能地降低故障帶來(lái)的影響,Redis也提供了完善的故障恢復(fù)機(jī)制:哨兵。

        下面就來(lái)具體來(lái)看看Redis的故障恢復(fù)是如何做的,以及其中的原理。

        部署模式

        Redis在部署時(shí),可以采用多種方式部署,每種部署方式對(duì)應(yīng)不同的可用級(jí)別。

        單節(jié)點(diǎn)部署:只有一個(gè)節(jié)點(diǎn)提供服務(wù),讀寫(xiě)均在此節(jié)點(diǎn),此節(jié)點(diǎn)宕機(jī)則數(shù)據(jù)全部丟失,直接影響業(yè)務(wù)。

        master-slave方式部署:兩個(gè)節(jié)點(diǎn)組成master-slave模式,在master上寫(xiě)入,slave上讀取,讀寫(xiě)分離提高訪問(wèn)性能,master宕機(jī)后,需要手動(dòng)把slave提升為master,業(yè)務(wù)影響程度取決于手動(dòng)提升master的延遲。

        master-slave+哨兵方式部署:master-slave與上述相同,不同的是增加一組哨兵節(jié)點(diǎn),用于實(shí)時(shí)檢查master的健康狀態(tài),在master宕機(jī)后自動(dòng)提升slave為新的master,最大程度降低不可用的時(shí)間,對(duì)業(yè)務(wù)影響時(shí)間較短。

        從上面幾種部署模式可以看出,提高Redis可用性的關(guān)鍵是:多副本部署 + 自動(dòng)故障恢復(fù),而多副本正是依賴(lài)主從復(fù)制。

        高可用做法

        Redis原生提供master-slave數(shù)據(jù)復(fù)制,保證slave永遠(yuǎn)與master數(shù)據(jù)保持一致。

        在master發(fā)生問(wèn)題時(shí),我們需要把slave提升為master,繼續(xù)提供服務(wù)。而這個(gè)提升新master的操作,如果是人工處理,必然無(wú)法保證及時(shí)性,所以Redis提供了哨兵節(jié)點(diǎn),用來(lái)管理master-slave節(jié)點(diǎn),并在master發(fā)生問(wèn)題時(shí),能夠自動(dòng)進(jìn)行故障恢復(fù)操作。

        整個(gè)故障恢復(fù)的工作,正是Redis哨兵自動(dòng)完成的。

        哨兵介紹

        哨兵是Redis高可用的解決方案,它是一個(gè)管理多個(gè)Redis實(shí)例的服務(wù)工具,可以實(shí)現(xiàn)對(duì)Redis實(shí)例的監(jiān)控、通知、自動(dòng)故障轉(zhuǎn)移。

        在部署哨兵時(shí),我們只需要在配置文件中配置需要管理的master節(jié)點(diǎn),哨兵節(jié)點(diǎn)就可以根據(jù)配置,對(duì)Redis節(jié)點(diǎn)進(jìn)行管理,實(shí)現(xiàn)高可用。

        一般我們需要部署多個(gè)哨兵節(jié)點(diǎn),這是因?yàn)樵诜植际綀?chǎng)景下,要想確定某個(gè)機(jī)器的某個(gè)節(jié)點(diǎn)上否發(fā)生故障,只用一臺(tái)機(jī)器去檢測(cè)可能是不準(zhǔn)確的,很有可能這兩臺(tái)機(jī)器的網(wǎng)絡(luò)發(fā)生了故障,而節(jié)點(diǎn)本身并沒(méi)有問(wèn)題。

        所以對(duì)于節(jié)點(diǎn)健康檢測(cè)的場(chǎng)景,一般都會(huì)采用多個(gè)節(jié)點(diǎn)同時(shí)去檢測(cè),且多個(gè)節(jié)點(diǎn)分布在不同機(jī)器上,節(jié)點(diǎn)數(shù)量為奇數(shù)個(gè),避免因?yàn)榫W(wǎng)絡(luò)分區(qū)導(dǎo)致哨兵決策錯(cuò)誤。這樣多個(gè)哨兵節(jié)點(diǎn)互相交換檢測(cè)信息,最終決策才能確認(rèn)某個(gè)節(jié)點(diǎn)上否真正發(fā)生了問(wèn)題。

        哨兵節(jié)點(diǎn)部署并配置完成后,哨兵就會(huì)自動(dòng)地對(duì)配置的master-slave進(jìn)行管理,在master發(fā)生故障時(shí),及時(shí)地提升slave為新的master,保證可用性。

        那么它的工作原理上怎樣的呢?

        哨兵工作原理

        哨兵的工作流程主要分為以下幾個(gè)階段:

        • 狀態(tài)感知

        • 心跳檢測(cè)

        • 選舉哨兵領(lǐng)導(dǎo)者

        • 選擇新的master

        • 故障恢復(fù)

        • 客戶(hù)端感知新master

        下面對(duì)這些階段進(jìn)行詳細(xì)的介紹。

        狀態(tài)感知

        哨兵啟動(dòng)后只指定了master的地址,哨兵要想在master故障時(shí)進(jìn)行故障恢復(fù),就需要知道每個(gè)master對(duì)應(yīng)的slave信息。每個(gè)master可能不止一個(gè)slave,因此哨兵需要知道整個(gè)集群中完整的的拓?fù)潢P(guān)系,如何拿到這些信息?

        哨兵每隔10秒會(huì)向每個(gè)master節(jié)點(diǎn)發(fā)送info命令,info命令返回的信息中,包含了主從拓?fù)潢P(guān)系,其中包括每個(gè)slave的地址和端口號(hào)。有了這些信息后,哨兵就會(huì)記住這些節(jié)點(diǎn)的拓?fù)湫畔ⅲ诤罄m(xù)發(fā)生故障時(shí),選擇合適的slave節(jié)點(diǎn)進(jìn)行故障恢復(fù)。

        哨兵除了向master發(fā)送info之外,還會(huì)向每個(gè)master節(jié)點(diǎn)特殊的pubsub中發(fā)送master當(dāng)前的狀態(tài)信息和哨兵自身的信息,其他哨兵節(jié)點(diǎn)通過(guò)訂閱這個(gè)pubsub,就可以拿到每個(gè)哨兵發(fā)來(lái)的信息。

        這么做的目的主要有2個(gè):

        • 哨兵節(jié)點(diǎn)可以發(fā)現(xiàn)其他哨兵的加入,進(jìn)而方便多個(gè)哨兵節(jié)點(diǎn)通信,為后續(xù)共同協(xié)商提供基礎(chǔ)

        • 與其他哨兵節(jié)點(diǎn)交換master的狀態(tài)信息,為后續(xù)判斷master是否故障提供依據(jù)

        心跳檢測(cè)

        在故障發(fā)生時(shí),需要立即啟動(dòng)故障恢復(fù)機(jī)制,那么如何保證及時(shí)性呢?

        每個(gè)哨兵節(jié)點(diǎn)每隔1秒向master、slave、其他哨兵節(jié)點(diǎn)發(fā)送ping命令,如果對(duì)方能在指定時(shí)間內(nèi)響應(yīng),說(shuō)明節(jié)點(diǎn)健康存活。如果未在規(guī)定時(shí)間內(nèi)(可配置)響應(yīng),那么該哨兵節(jié)點(diǎn)認(rèn)為此節(jié)點(diǎn)主觀下線(xiàn)。

        為什么叫做主觀下線(xiàn)?

        因?yàn)楫?dāng)前哨兵節(jié)點(diǎn)探測(cè)對(duì)方?jīng)]有得到響應(yīng),很有可能這兩個(gè)機(jī)器之間的網(wǎng)絡(luò)發(fā)生了故障,而master節(jié)點(diǎn)本身沒(méi)有任何問(wèn)題,此時(shí)就認(rèn)為master故障是不正確的。

        要想確認(rèn)master節(jié)點(diǎn)是否真正發(fā)生故障,就需要多個(gè)哨兵節(jié)點(diǎn)共同確認(rèn)才行。

        每個(gè)哨兵節(jié)點(diǎn)通過(guò)向其他哨兵節(jié)點(diǎn)詢(xún)問(wèn)此master的狀態(tài),來(lái)共同確認(rèn)此節(jié)點(diǎn)上否真正故障。

        如果超過(guò)指定數(shù)量(可配置)的哨兵節(jié)點(diǎn)都認(rèn)為此節(jié)點(diǎn)主觀下線(xiàn),那么才會(huì)把這個(gè)節(jié)點(diǎn)標(biāo)記為客觀下線(xiàn)。

        選舉哨兵領(lǐng)導(dǎo)者

        確認(rèn)這個(gè)節(jié)點(diǎn)真正故障后,就需要進(jìn)入到故障恢復(fù)階段。如何進(jìn)行故障恢復(fù),也需要經(jīng)歷一系列流程。

        首先需要選舉出一個(gè)哨兵領(lǐng)導(dǎo)者,由這個(gè)專(zhuān)門(mén)的哨兵領(lǐng)導(dǎo)者來(lái)進(jìn)行故障恢復(fù)操作,不用多個(gè)哨兵都參與故障恢復(fù)。選舉哨兵領(lǐng)導(dǎo)者的過(guò)程,需要多個(gè)哨兵節(jié)點(diǎn)共同協(xié)商來(lái)選出。

        這個(gè)選舉協(xié)商的過(guò)程,在分布式領(lǐng)域中叫做達(dá)成共識(shí),協(xié)商的算法叫做共識(shí)算法。

        共識(shí)算法主要為了解決在分布式場(chǎng)景下,多個(gè)節(jié)點(diǎn)如何針對(duì)某一個(gè)場(chǎng)景達(dá)成一致的結(jié)果。

        共識(shí)算法包括很多種,例如Paxos、Raft、Gossip算法等,感興趣的同學(xué)可以自行搜索相關(guān)資料,這里不再展開(kāi)來(lái)講。

        哨兵選舉領(lǐng)導(dǎo)者的過(guò)程類(lèi)似于Raft算法,它的算法足夠簡(jiǎn)單易理解。

        簡(jiǎn)單來(lái)講流程如下:

        • 每個(gè)哨兵都設(shè)置一個(gè)隨機(jī)超時(shí)時(shí)間,超時(shí)后向其他哨兵發(fā)送申請(qǐng)成為領(lǐng)導(dǎo)者的請(qǐng)求

        • 其他哨兵只能對(duì)收到的第一個(gè)請(qǐng)求進(jìn)行回復(fù)確認(rèn)

        • 首先達(dá)到多數(shù)確認(rèn)選票的哨兵節(jié)點(diǎn),成為領(lǐng)導(dǎo)者

        • 如果在確認(rèn)回復(fù)后,所有哨兵都無(wú)法達(dá)到多數(shù)選票的結(jié)果,那么進(jìn)行重新選舉,直到選出領(lǐng)導(dǎo)者為止

        選擇出哨兵領(lǐng)導(dǎo)者后,之后的故障恢復(fù)操作都由這個(gè)哨兵領(lǐng)導(dǎo)者進(jìn)行操作。

        搜索Java知音公眾號(hào),回復(fù)“后端面試”,送你一份Java面試題寶典.pdf

        選擇新的master

        哨兵領(lǐng)導(dǎo)者針對(duì)發(fā)生故障的master節(jié)點(diǎn),需要在它的slave節(jié)點(diǎn)中,選擇一個(gè)節(jié)點(diǎn)來(lái)代替其工作。

        這個(gè)選擇新master過(guò)程也是有優(yōu)先級(jí)的,在多個(gè)slave的場(chǎng)景下,優(yōu)先級(jí)按照:slave-priority配置 > 數(shù)據(jù)完整性 > runid較小者進(jìn)行選擇。

        也就是說(shuō)優(yōu)先選擇slave-priority最小值的slave節(jié)點(diǎn),如果所有slave此配置相同,那么選擇數(shù)據(jù)最完整的slave節(jié)點(diǎn),如果數(shù)據(jù)也一樣,最后選擇runid較小的slave節(jié)點(diǎn)。

        提升新的master

        經(jīng)過(guò)優(yōu)先級(jí)選擇,選出了備選的master節(jié)點(diǎn)后,下一步就是要進(jìn)行真正的主從切換了。

        哨兵領(lǐng)導(dǎo)者給備選的master節(jié)點(diǎn)發(fā)送slaveof no one命令,讓該節(jié)點(diǎn)成為master。

        之后,哨兵領(lǐng)導(dǎo)者會(huì)給故障節(jié)點(diǎn)的所有slave發(fā)送slaveof $newmaster命令,讓這些slave成為新master的從節(jié)點(diǎn),開(kāi)始從新的master上同步數(shù)據(jù)。

        最后哨兵領(lǐng)導(dǎo)者把故障節(jié)點(diǎn)降級(jí)為slave,并寫(xiě)入到自己的配置文件中,待這個(gè)故障節(jié)點(diǎn)恢復(fù)后,則自動(dòng)成為新master節(jié)點(diǎn)的slave。

        至此,整個(gè)故障切換完成。

        客戶(hù)端感知新master

        最后,客戶(hù)端如何拿到最新的master地址呢?

        哨兵在故障切換完成之后,會(huì)向自身節(jié)點(diǎn)的指定pubsub中寫(xiě)入一條信息,客戶(hù)端可以訂閱這個(gè)pubsub來(lái)感知master的變化通知。我們的客戶(hù)端也可以通過(guò)在哨兵節(jié)點(diǎn)主動(dòng)查詢(xún)當(dāng)前最新的master,來(lái)拿到最新的master地址。

        另外,哨兵還提供了“鉤子”機(jī)制,我們也可以在哨兵配置文件中配置一些腳本邏輯,在故障切換完成時(shí),觸發(fā)“鉤子”邏輯,通知客戶(hù)端發(fā)生了切換,讓客戶(hù)端重新在哨兵上獲取最新的master地址。

        一般來(lái)說(shuō),推薦采用第一種方式進(jìn)行處理,很多客戶(hù)端SDK中已經(jīng)集成好了從哨兵節(jié)點(diǎn)獲取最新master的方法,我們直接使用即可。

        總結(jié)

        可見(jiàn),為了保證Redis的高可用,哨兵節(jié)點(diǎn)要準(zhǔn)確無(wú)誤地判斷故障的發(fā)生,并且快速的選出新的節(jié)點(diǎn)來(lái)代替其提供服務(wù),這中間的流程還是比較復(fù)雜的。

        中間涉及到了分布式共識(shí)、分布式協(xié)商等知識(shí),目的都是為了保證故障切換的準(zhǔn)確性。

        我們有必要了解Redis高可用的工作原理,這樣我們?cè)谑褂肦edis時(shí)能更準(zhǔn)確地使用它。

        點(diǎn)個(gè)在看支持我吧,轉(zhuǎn)發(fā)就更好了
        瀏覽 20
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            好大好想要好爽好深 | 亚洲影视一区 | 孙头退休后日女儿的幸福生活 | 亚洲成人无码在线 | 亚洲免费在线视频 | 先锋AV啪啪资源站 | 免费国产黄色网址 | 熟妇人妻中文字幕无码老熟妇 | 九九热这里只有精品23 | 大香蕉伊人在线观看视频 |