10.6、故障轉(zhuǎn)移

故障轉(zhuǎn)移

Redis集群自身實(shí)現(xiàn)了高可用。高可用首先需要解決集群部分失敗的場(chǎng)景:當(dāng)集群內(nèi)少量節(jié)點(diǎn)出現(xiàn)故障時(shí)通過(guò)自動(dòng)故障轉(zhuǎn)移保證集群可以正常對(duì)外提供服務(wù)服赎。本節(jié)介紹故障轉(zhuǎn)移的細(xì)節(jié),分析故障發(fā)現(xiàn)和替換故障節(jié)點(diǎn)的過(guò)程交播。

  1. 故障發(fā)現(xiàn)

    當(dāng)集群內(nèi)某個(gè)節(jié)點(diǎn)出現(xiàn)問(wèn)題時(shí)重虑,需要通過(guò)一種健壯的方式保證識(shí)別出節(jié)點(diǎn)是否發(fā)生了故障。Redis集群內(nèi)節(jié)點(diǎn)通過(guò)ping/pong消息實(shí)現(xiàn)節(jié)點(diǎn)通信秦士,消息不但可以傳播節(jié)點(diǎn)槽信息嚎尤,還可以傳播其他狀態(tài)如:主從狀態(tài)、節(jié)點(diǎn)狀態(tài)等伍宦。因此故障發(fā)現(xiàn)也是通過(guò)消息傳播機(jī)制實(shí)現(xiàn)的芽死,主要環(huán)節(jié)包括:主觀下線(pfail)和客觀下線(fail)。

    • 主觀下線:指某個(gè)節(jié)點(diǎn)認(rèn)為另一個(gè)節(jié)點(diǎn)不可用次洼,即下線狀態(tài)关贵,這個(gè)狀態(tài)并不是最終的故障判定,只能代表一個(gè)節(jié)點(diǎn)的意見(jiàn)卖毁,可能存在誤判情況揖曾。

    • 客觀下線:指標(biāo)記一個(gè)節(jié)點(diǎn)真正的下線,集群內(nèi)多個(gè)節(jié)點(diǎn)都認(rèn)為該節(jié)點(diǎn)不可用亥啦,從而達(dá)成共識(shí)的結(jié)果炭剪。如果是持有槽的主節(jié)點(diǎn)故障,需要為該節(jié)點(diǎn)進(jìn)行故障轉(zhuǎn)移翔脱。

    1. 主觀下線

      集群中每個(gè)節(jié)點(diǎn)都會(huì)定期向其他節(jié)點(diǎn)發(fā)送ping消息奴拦,接收節(jié)點(diǎn)回復(fù)pong消息作為響應(yīng)。如果在cluster-node-timeout時(shí)間內(nèi)通信一直失敗届吁,則發(fā)送節(jié)點(diǎn)會(huì)認(rèn)為接收節(jié)點(diǎn)存在故障错妖,把接受節(jié)點(diǎn)標(biāo)記為主觀下線(pfail)狀態(tài)绿鸣。

      流程說(shuō)明:

      1)節(jié)點(diǎn)a發(fā)送ping消息給節(jié)點(diǎn)b,如果通信正常接收到pong消息暂氯,節(jié)點(diǎn)a更新最近一次與節(jié)點(diǎn)b的通信時(shí)間潮模。

      2)如果節(jié)點(diǎn)a與節(jié)點(diǎn)b通信出現(xiàn)問(wèn)題則斷開(kāi)連接,下次會(huì)進(jìn)行重連痴施。如果一致通信失敗擎厢,則節(jié)點(diǎn)a記錄的節(jié)點(diǎn)b最后通信時(shí)間將無(wú)法更新。

      3)節(jié)點(diǎn)a內(nèi)的定時(shí)任務(wù)檢測(cè)到與節(jié)點(diǎn)b最后通信時(shí)間超高cluster-node-timeout時(shí)辣吃,更新本地對(duì)節(jié)點(diǎn)b的狀態(tài)為主觀下線(pfail)锉矢。

      主觀下線簡(jiǎn)單來(lái)講就是,當(dāng)cluster-note-timeout時(shí)間內(nèi)某節(jié)點(diǎn)無(wú)法與另一個(gè)節(jié)點(diǎn)順利完成ping消息通信時(shí)齿尽,則將該節(jié)點(diǎn)標(biāo)記為主觀下線狀態(tài)沽损。每個(gè)節(jié)點(diǎn)內(nèi)的clusterState結(jié)構(gòu)都需要保存其他節(jié)點(diǎn)信息,用于自身視角判斷其他節(jié)點(diǎn)的狀態(tài)循头。結(jié)構(gòu)關(guān)鍵屬性如下:

      typedef struct clusterState {
          clusterNode *myself; /* 自身節(jié)點(diǎn) */
          dict *nodes; /* 當(dāng)前集群內(nèi)所有節(jié)點(diǎn)的字典集合绵估,key為節(jié)點(diǎn)ID,value為對(duì)應(yīng)節(jié)點(diǎn)ClusterNode結(jié)構(gòu) */
          ...
      } clusterState;
      

      字典nodes屬性中的clusterNode結(jié)構(gòu)保存了節(jié)點(diǎn)的狀態(tài)卡骂,關(guān)鍵屬性如下:

      typedef struct clusterNode {
          int flags; /* 當(dāng)前節(jié)點(diǎn)狀態(tài)国裳,如:主從角色,是否下線等 */
          mstime_t ping_sent; /* 最后一次與該節(jié)點(diǎn)發(fā)送ping消息的時(shí)間 */
          mstime_t pong_received; /* 最后一次接收到該節(jié)點(diǎn)pong消息的時(shí)間 */
          ...
      } clusterNode;
      

      其中最重要的屬性是flags全跨,用于標(biāo)示該節(jié)點(diǎn)對(duì)應(yīng)狀態(tài)缝左,取值范圍如下:

      CLUSTER_NODE_MASTER 1 /* 當(dāng)前為主節(jié)點(diǎn) */
      CLUSTER_NODE_SLAVE 2 /* 當(dāng)前為從節(jié)點(diǎn) */
      CLUSTER_NODE_PFAIL 4 /* 主觀下線狀態(tài) */
      CLUSTER_NODE_FAIL 8 /* 客觀下線狀態(tài) */
      CLUSTER_NODE_MYSELF 16 /* 表示自身狀態(tài) */
      CLUSTER_NODE_HANDSHAKE 32 /* 握手狀態(tài),未與其他節(jié)點(diǎn)進(jìn)行消息通信 */
      CLUSTER_NODE_NOADDR 64 /* 無(wú)地址節(jié)點(diǎn)浓若,用于第一次meet通信未完成或者通信失敗 */
      CLUSTER_NODE_MEET 128 /* 需要接受meet消息的節(jié)點(diǎn)狀態(tài) */
      CLUSTER_NODE_MIGRATE_TO 256 /* 該節(jié)點(diǎn)被選中為新的主節(jié)點(diǎn)狀態(tài) */
      

      Redis集群對(duì)于節(jié)點(diǎn)最終是否故障判斷非常嚴(yán)謹(jǐn)渺杉,只有一個(gè)節(jié)點(diǎn)認(rèn)為主觀下線并不能準(zhǔn)確判斷是否故障。

    2. 客觀下線

      當(dāng)某個(gè)節(jié)點(diǎn)判斷另一個(gè)節(jié)點(diǎn)主觀下線后挪钓,相應(yīng)的節(jié)點(diǎn)狀態(tài)會(huì)跟隨消息在集群內(nèi)傳播是越。ping/pong消息的消息體會(huì)攜帶集群1/10的其他節(jié)點(diǎn)狀態(tài)數(shù)據(jù),當(dāng)接受節(jié)點(diǎn)發(fā)現(xiàn)消息體中含有主觀下線的節(jié)點(diǎn)狀態(tài)是碌上,會(huì)在本地找到故障節(jié)點(diǎn)的ClusterNode結(jié)構(gòu)倚评,保存到下線報(bào)告鏈表中。結(jié)構(gòu)如下:

      struct clusterNode { /* 認(rèn)為是主觀下線的clusterNode結(jié)構(gòu) */
          list *fail_reports; /* 記錄了所有其他節(jié)點(diǎn)對(duì)該節(jié)點(diǎn)的下線報(bào)告 */
          ...
      };
      

      通過(guò)Gossip消息傳播馏予,集群內(nèi)節(jié)點(diǎn)不斷收集到故障節(jié)點(diǎn)的下線報(bào)告天梧。當(dāng)半數(shù)以上持有槽的主節(jié)點(diǎn)都標(biāo)記某個(gè)節(jié)點(diǎn)是主觀下線時(shí)。觸發(fā)客觀下線流程霞丧。這里有兩個(gè)問(wèn)題:

      1)為什么必須是負(fù)責(zé)槽的主節(jié)點(diǎn)參與故障發(fā)現(xiàn)決策呢岗?因?yàn)榧耗J较轮挥刑幚聿鄣闹鞴?jié)點(diǎn)才負(fù)責(zé)讀寫(xiě)請(qǐng)求和集群槽等關(guān)鍵信息維護(hù),而從節(jié)點(diǎn)只進(jìn)行主機(jī)誒單數(shù)據(jù)和狀態(tài)信息的復(fù)制。

      2)為什么半數(shù)以上處理槽的主節(jié)點(diǎn)敷燎?必須半數(shù)以上是為了應(yīng)對(duì)網(wǎng)絡(luò)分區(qū)等原因造成的集群分割情況暂筝,被分割的小集群因?yàn)闊o(wú)法完成主觀下線到客觀下線這一關(guān)鍵過(guò)程箩言,從而防止小集群完成故障轉(zhuǎn)移之后繼續(xù)對(duì)外提供服務(wù)硬贯。

      假設(shè)節(jié)點(diǎn)a標(biāo)記節(jié)點(diǎn)b為主管下線,一段時(shí)間后節(jié)點(diǎn)a通過(guò)消息把節(jié)點(diǎn)b的狀態(tài)發(fā)送到其他節(jié)點(diǎn)陨收,當(dāng)節(jié)點(diǎn)c接受到消息并解析出消息體含有節(jié)點(diǎn)b的pfail狀態(tài)是饭豹,會(huì)觸發(fā)客觀下線流程:

      1)當(dāng)消息體內(nèi)含有其他節(jié)點(diǎn)的pfail狀態(tài)會(huì)判斷發(fā)送節(jié)點(diǎn)的狀態(tài),如果發(fā)送節(jié)點(diǎn)是主節(jié)點(diǎn)則對(duì)報(bào)告的pfail狀態(tài)處理务漩,從節(jié)點(diǎn)則忽略拄衰。

      2)找到pfail對(duì)應(yīng)的節(jié)點(diǎn)結(jié)構(gòu),更新clusterNode內(nèi)部下線報(bào)告鏈表饵骨。

      3)根據(jù)更新后的下線報(bào)告鏈表嘗試進(jìn)行客觀下線翘悉。

      這里針對(duì)維護(hù)下線報(bào)告和嘗試客戶端下線邏輯進(jìn)行詳細(xì)說(shuō)明。

      (1)維護(hù)下線報(bào)告鏈表

      每個(gè)節(jié)點(diǎn)ClusterNode結(jié)構(gòu)中都會(huì)存在一個(gè)下線鏈表結(jié)構(gòu)居触,保存了其他主節(jié)點(diǎn)針對(duì)當(dāng)前節(jié)點(diǎn)的下線報(bào)告妖混,結(jié)構(gòu)如下:

      typedef struct clusterNodeFailReport {
          struct clusterNode *node; /*  */
          mstime_t time; /*  */
      } clusterNodeFailReport;
      

      下線報(bào)告中保存了報(bào)告故障的節(jié)點(diǎn)結(jié)構(gòu)和最近收到下線報(bào)告的時(shí)間,當(dāng)接收到fail狀態(tài)時(shí)轮洋,會(huì)維護(hù)對(duì)應(yīng)節(jié)點(diǎn)的下線上報(bào)鏈表制市。每個(gè)下線報(bào)告都存在有效期,每次在嘗試觸發(fā)客觀下線時(shí)弊予,都會(huì)檢測(cè)下線報(bào)告是否過(guò)期祥楣,對(duì)于過(guò)期的下線報(bào)告將被刪除。如果在cluster-node-time * 2的時(shí)間內(nèi)該下線報(bào)告沒(méi)有得到更新則過(guò)期并刪除汉柒。下線報(bào)告的有效期限是server.cluster_node_timeout * 2误褪,主要是針對(duì)故障誤報(bào)的情況。例如節(jié)點(diǎn)A在上一個(gè)小時(shí)報(bào)告節(jié)點(diǎn)B主觀下線碾褂,但是之后又恢復(fù)正痴窦幔。現(xiàn)在又有其他節(jié)點(diǎn)上報(bào)節(jié)點(diǎn)B主觀下線斋扰,根據(jù)實(shí)際情況之前的屬于誤報(bào)不能被使用渡八。

      運(yùn)維提示:如果在cluster-node-time * 2時(shí)間內(nèi)無(wú)法收集到一半以上槽節(jié)點(diǎn)的下線報(bào)告,那么之前的下線報(bào)告將會(huì)過(guò)期传货,也就是說(shuō)主觀下線上報(bào)的速度追趕不上下線報(bào)告過(guò)期的速度屎鳍,那么故障節(jié)點(diǎn)將永遠(yuǎn)無(wú)法被標(biāo)記為客觀下線從而導(dǎo)致故障轉(zhuǎn)移失敗。因此不建議將cluster-node-time設(shè)置得過(guò)小问裕。

      (2)嘗試客觀下線

      集群中的節(jié)點(diǎn)每次接收到其他節(jié)點(diǎn)的pfail狀態(tài)逮壁,都會(huì)嘗試觸發(fā)客觀下線,流程如下:

      1)首先統(tǒng)計(jì)有效的下線報(bào)告數(shù)量粮宛,如果小于集群內(nèi)持有槽的主節(jié)點(diǎn)總數(shù)的一半則退出窥淆。

      2)當(dāng)下線報(bào)告大于槽主節(jié)點(diǎn)數(shù)量一半時(shí)卖宠,標(biāo)記對(duì)應(yīng)故障節(jié)點(diǎn)為客觀下線狀態(tài)。

      3)向集群廣播一條fail消息忧饭,通知所有的節(jié)點(diǎn)將故障節(jié)點(diǎn)標(biāo)記為客觀下線扛伍,fail消息的消息體只包含故障節(jié)點(diǎn)的ID。

      廣播fail消息是客觀下線的最后一步词裤,它承擔(dān)著非常重要的職責(zé):

      • 通知集群內(nèi)所有的節(jié)點(diǎn)標(biāo)記故障節(jié)點(diǎn)為客觀下線狀態(tài)并立刻生效刺洒。

      • 通知故障節(jié)點(diǎn)的從節(jié)點(diǎn)觸發(fā)故障轉(zhuǎn)移流程。

      需要理解的是吼砂,盡管存在廣播fail消息機(jī)制逆航,但是集群所有節(jié)點(diǎn)知道故障故障節(jié)點(diǎn)進(jìn)入客觀下線狀態(tài)是不確定的。比如當(dāng)出現(xiàn)網(wǎng)絡(luò)分區(qū)時(shí)有可能集群被分割為一大一小兩個(gè)獨(dú)立集群中渔肩。大的集群持有半數(shù)槽節(jié)點(diǎn)可以完成客觀下線并廣播fail消息因俐,但是小集群無(wú)法接收到fail消息。當(dāng)時(shí)當(dāng)網(wǎng)絡(luò)恢復(fù)后周偎,只要故障節(jié)點(diǎn)變?yōu)榭陀^下線抹剩,最終總會(huì)通過(guò)Gossip消息傳播至集群的所有節(jié)點(diǎn)。

      運(yùn)維提示:網(wǎng)絡(luò)分區(qū)會(huì)導(dǎo)致分割后的小集群無(wú)法收到大集群的fail消息栏饮,因此如果故障節(jié)點(diǎn)所有的從節(jié)點(diǎn)都在小集群內(nèi)將導(dǎo)致無(wú)法完成后續(xù)故障轉(zhuǎn)移吧兔,因此部署主從結(jié)構(gòu)時(shí)需要根據(jù)自身機(jī)房/機(jī)架拓?fù)浣Y(jié)構(gòu),降低主從被分區(qū)的可能性袍嬉。

  2. 故障恢復(fù)

    故障節(jié)點(diǎn)變?yōu)榭陀^下線后境蔼,如果下線節(jié)點(diǎn)是持有槽的主節(jié)點(diǎn)則需要在它的從節(jié)點(diǎn)中選出一個(gè)替換它,從而保證集群的高可用伺通。下線主節(jié)點(diǎn)的所有從節(jié)點(diǎn)承擔(dān)故障恢復(fù)的義務(wù)箍土,當(dāng)從節(jié)點(diǎn)通過(guò)內(nèi)部定時(shí)任務(wù)發(fā)現(xiàn)自身復(fù)制的主節(jié)點(diǎn)進(jìn)入客觀下線時(shí),將會(huì)觸發(fā)故障恢復(fù)流程:

    1. 資格檢查

      每個(gè)從節(jié)點(diǎn)都要檢查最后與主節(jié)點(diǎn)斷線時(shí)間罐监,判斷是否有資格替換故障的主節(jié)點(diǎn)吴藻。如果從節(jié)點(diǎn)與主節(jié)點(diǎn)斷線時(shí)間超過(guò)cluster-node-time * cluster-slave-validity-factor,則當(dāng)前從節(jié)點(diǎn)不具備故障轉(zhuǎn)移資格弓柱。參數(shù)cluster-slave-validity-factor用于從節(jié)點(diǎn)的有效因子沟堡,默認(rèn)為10.

    2. 準(zhǔn)備選舉時(shí)間

      當(dāng)從節(jié)點(diǎn)符合故障轉(zhuǎn)移資格后,更新觸發(fā)故障選舉的時(shí)間矢空,只有到達(dá)該時(shí)間后才能執(zhí)行后續(xù)流程航罗。故障選舉時(shí)間相關(guān)字段如下:

      struct clusterState {
          ...
          mstime_t failover_auth_time; /* 記錄之前或者下次將要執(zhí)行故障選舉時(shí)間 */
          int failover_auth_rank; /* 記錄當(dāng)前從節(jié)點(diǎn)排名 */
      }
      

      這里之所以采用延遲觸發(fā)機(jī)制,主要是通過(guò)多個(gè)從節(jié)點(diǎn)使用不同的延遲選舉時(shí)間來(lái)支持優(yōu)先級(jí)問(wèn)題屁药。復(fù)制偏移量越大說(shuō)明從節(jié)點(diǎn)延遲越低粥血,那么它應(yīng)該具有更高的優(yōu)先級(jí)來(lái)替換故障主節(jié)點(diǎn)。

    3. 發(fā)起選舉

      當(dāng)從節(jié)點(diǎn)定時(shí)任務(wù)檢測(cè)到達(dá)故障選舉時(shí)間(failover_auth_time)到達(dá)后,發(fā)起選舉流程如下:

      (1)更新配置紀(jì)元

      配置紀(jì)元是一個(gè)只增不減的整數(shù)复亏,每個(gè)主節(jié)點(diǎn)自身維護(hù)一個(gè)配置紀(jì)元(clusterNode.configEpoch)標(biāo)示當(dāng)前主節(jié)點(diǎn)的版本趾娃,所有主節(jié)點(diǎn)的配置紀(jì)元都不相等,從節(jié)點(diǎn)會(huì)復(fù)制主節(jié)點(diǎn)的配置紀(jì)元缔御。整個(gè)集群又維護(hù)一個(gè)全局的配置紀(jì)元(clusterState.currentEpoch)抬闷,用于記錄集群內(nèi)所有主節(jié)點(diǎn)配置紀(jì)元的最大版本。執(zhí)行cluster info命令可以查看配置紀(jì)元信息:

      127.0.0.1:6379> cluster info
      ...
      cluster_current_epoch:15    //整個(gè)集群最大配置紀(jì)元
      cluster_my_epoch:13         //當(dāng)前主節(jié)點(diǎn)配置紀(jì)元
      

      配置紀(jì)元會(huì)跟隨ping/pong消息在集群內(nèi)傳播刹淌,當(dāng)發(fā)送方與接收方都是主節(jié)點(diǎn)且配置紀(jì)元相等時(shí)代表出現(xiàn)了沖突饶氏,nodeId更大的一方會(huì)遞增全局配置紀(jì)元并賦值給當(dāng)前節(jié)點(diǎn)來(lái)區(qū)分沖突讥耗。

      配置紀(jì)元的主要作用:

      • 標(biāo)示集群每個(gè)主節(jié)點(diǎn)的不同版本和當(dāng)前集群最大的版本有勾。

      • 每次集群發(fā)生重要事件時(shí),這里的重要事件值出現(xiàn)新的主節(jié)點(diǎn)(新加入的或者由從節(jié)點(diǎn)轉(zhuǎn)換而來(lái))古程,從節(jié)點(diǎn)競(jìng)爭(zhēng)選舉蔼卡。都會(huì)遞增集群全局的配置紀(jì)元并賦值給相關(guān)主節(jié)點(diǎn),用于記錄這一關(guān)鍵事件挣磨。

      • 主節(jié)點(diǎn)具有更大的配置紀(jì)元代表了更新的集群狀態(tài)雇逞,因此當(dāng)節(jié)點(diǎn)間進(jìn)行ping/pong消息交換時(shí),如出現(xiàn)slots等關(guān)鍵信息不一致時(shí)茁裙,以配置紀(jì)元更大的一方為準(zhǔn)塘砸,防止過(guò)時(shí)的消息狀態(tài)污染集群。

      配置紀(jì)元的應(yīng)用場(chǎng)景有:

      • 新節(jié)點(diǎn)加入
      • 槽節(jié)點(diǎn)映射沖突檢測(cè)晤锥。
      • 從節(jié)點(diǎn)投票選舉沖突檢測(cè)掉蔬。

      開(kāi)發(fā)提示:之前在通過(guò)cluster setslot命令修改槽節(jié)點(diǎn)映射時(shí),需要確保執(zhí)行請(qǐng)求的主節(jié)點(diǎn)本地配置紀(jì)元(configEpoch)是最大值矾瘾,否則修改后的槽信息在消息傳播中不會(huì)被擁有更高的配置紀(jì)元的節(jié)點(diǎn)采納女轿。由于Gossip通信機(jī)制無(wú)法準(zhǔn)確知道當(dāng)前最大的配置紀(jì)元在哪個(gè)節(jié)點(diǎn),因此在槽遷移任務(wù)最后的cluster setslot {slot} node {nodeId}命令需要在全部主節(jié)點(diǎn)中執(zhí)行一遍壕翩。

      從節(jié)點(diǎn)每次發(fā)起投票時(shí)都會(huì)自增集群的全局配置紀(jì)元蛉迹,并單獨(dú)保存在clusterState,failover_auth_epoch變量中國(guó)用于標(biāo)識(shí)本次從節(jié)點(diǎn)發(fā)起選舉的版本放妈。

      (2)廣播選舉消息

      在集群內(nèi)廣播選舉消息(FAILOVER_AUTH_REQUEST)北救,并記錄已發(fā)送過(guò)消息的狀態(tài),保證該從節(jié)點(diǎn)在一個(gè)配置紀(jì)元內(nèi)只能發(fā)起一次選舉芜抒。消息內(nèi)容如同ping消息只是將type類型變?yōu)镕AILOVER_AUTH_REQUEST珍策。

    4. 選舉投票

      只有持有槽的主節(jié)點(diǎn)才會(huì)處理故障選舉消息(FAILOVER_AUTH_REQUEST),因?yàn)槊總€(gè)持有槽的節(jié)點(diǎn)在一個(gè)配置紀(jì)元內(nèi)都有唯一的一張選票挽绩,當(dāng)接到第一個(gè)請(qǐng)求投票的從節(jié)點(diǎn)消息時(shí)回復(fù)FAILOVER_AUTH_ACK消息作為投票膛壹,之后相同配置紀(jì)元內(nèi)其他從節(jié)點(diǎn)的選舉消息將忽略。

      投票過(guò)程其實(shí)是一個(gè)領(lǐng)導(dǎo)者選舉的過(guò)程,如集群內(nèi)又N個(gè)持有槽的主節(jié)點(diǎn)代表有N張選票模聋。由于在每個(gè)配置紀(jì)元內(nèi)持有槽的主節(jié)點(diǎn)只能投票給一個(gè)從節(jié)點(diǎn)肩民,因此只能有一個(gè)從節(jié)點(diǎn)獲得N/2+1的選票,保證能夠找出唯一的從節(jié)點(diǎn)链方。

      Redis集群沒(méi)有直接使用從節(jié)點(diǎn)記性領(lǐng)導(dǎo)者選舉持痰,主要因?yàn)閺墓?jié)點(diǎn)數(shù)必須大于等于3個(gè)才能保證湊夠N/2+1個(gè)節(jié)點(diǎn),將導(dǎo)致從節(jié)點(diǎn)資源浪費(fèi)祟蚀。使用集群內(nèi)所有持有槽的主節(jié)點(diǎn)進(jìn)行領(lǐng)導(dǎo)者選舉工窍,即使只有一個(gè)從節(jié)點(diǎn)也可以完成選舉過(guò)程。

      當(dāng)從節(jié)點(diǎn)收集到N/2+1個(gè)持有槽的主節(jié)點(diǎn)投票時(shí)前酿,從節(jié)點(diǎn)可以執(zhí)行替換主機(jī)誒單操作患雏,例如集群內(nèi)有5個(gè)持有槽的主節(jié)點(diǎn),主節(jié)點(diǎn)b故障后還有4個(gè)罢维,當(dāng)其中一個(gè)從節(jié)點(diǎn)收集到3張投票時(shí)代表獲得了足夠的選票可以進(jìn)行替換主節(jié)點(diǎn)操作淹仑。

      運(yùn)維提示:故障主節(jié)點(diǎn)也算在投票數(shù)內(nèi),假設(shè)集群內(nèi)節(jié)點(diǎn)規(guī)模是3主3從肺孵,其中有2個(gè)主節(jié)點(diǎn)部署在一臺(tái)機(jī)器上匀借,當(dāng)這臺(tái)機(jī)器宕機(jī)時(shí),由于從節(jié)點(diǎn)無(wú)法收集到3/2+1個(gè)主機(jī)誒單選票將導(dǎo)致故障轉(zhuǎn)移失敗平窘。這個(gè)問(wèn)題也是用于故障發(fā)現(xiàn)環(huán)節(jié)吓肋。因此部署集群時(shí)所有主節(jié)點(diǎn)最少需要部署在3臺(tái)物理機(jī)上才能避免單點(diǎn)問(wèn)題。

      投票作廢: 每個(gè)配置紀(jì)元代表依次選舉周期瑰艘,如果在開(kāi)始投票之后的cluster-node-timeout * 2時(shí)間內(nèi)從節(jié)點(diǎn)沒(méi)有獲取足夠數(shù)量的投票是鬼,則本次選舉作廢。從節(jié)點(diǎn)對(duì)配置紀(jì)元自增并發(fā)起下一輪投票磅叛,知道選舉成功為止屑咳。

    5. 替換主節(jié)點(diǎn)

      當(dāng)從節(jié)點(diǎn)收集到足夠的選票之后,觸發(fā)替換主節(jié)點(diǎn)操作:

      1)當(dāng)前從節(jié)點(diǎn)取消復(fù)制變?yōu)橹鞴?jié)點(diǎn)弊琴。

      2)執(zhí)行clusterDelSlot操作撤銷故障主節(jié)點(diǎn)負(fù)責(zé)的槽兆龙,并執(zhí)行clusterAddSlot把這些槽委派給自己。

      3)向集群廣播自己的pong消息敲董,通知集群內(nèi)所有的節(jié)點(diǎn)當(dāng)前從節(jié)點(diǎn)變?yōu)橹鞴?jié)點(diǎn)并接管了故障主節(jié)點(diǎn)的槽信息紫皇。

  3. 故障轉(zhuǎn)移時(shí)間

    在介紹完故障發(fā)現(xiàn)和恢復(fù)的流程后,這時(shí)我們可以估算出故障轉(zhuǎn)移時(shí)間:

    1)主觀下線(pfail)識(shí)別時(shí)間=cluster-node-timeout

    2)主觀下線狀態(tài)消息傳播時(shí)間<=cluster-node-timeout/2腋寨。消息通信機(jī)制對(duì)超過(guò)cluster-node-timeout/2未通信節(jié)點(diǎn)會(huì)發(fā)起ping消息聪铺,消息體在選擇包含哪些節(jié)點(diǎn)時(shí)會(huì)優(yōu)先選取下線狀態(tài)節(jié)點(diǎn),所以通常這段時(shí)間內(nèi)能夠收集到半數(shù)以上主節(jié)點(diǎn)的pfail報(bào)告從而完成故障發(fā)現(xiàn)萄窜。

    3)從節(jié)點(diǎn)轉(zhuǎn)移時(shí)間<=1000毫秒铃剔。由于存在延遲發(fā)起選舉機(jī)制撒桨,偏移量最大的從節(jié)點(diǎn)會(huì)最多延遲一秒發(fā)起選舉。通常第一次選舉就會(huì)成功键兜,所以從節(jié)點(diǎn)執(zhí)行轉(zhuǎn)移時(shí)間在1秒以內(nèi)凤类。

    根據(jù)以上分析可以預(yù)估出故障轉(zhuǎn)移時(shí)間,如下:

    failover-time(毫秒) <= cluster-node-timeout + cluster-node-timeout/2 + 1000
    

    因此普气,故障轉(zhuǎn)移時(shí)間跟cluster-node-timeout參數(shù)息息相關(guān)谜疤,默認(rèn)15秒。配置時(shí)可以根據(jù)業(yè)務(wù)容忍度做出適當(dāng)調(diào)整现诀,但不是越小越好夷磕,下一節(jié)的帶寬消耗部分進(jìn)一步說(shuō)明。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仔沿,一起剝皮案震驚了整個(gè)濱河市坐桩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌于未,老刑警劉巖撕攒,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陡鹃,死亡現(xiàn)場(chǎng)離奇詭異烘浦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)萍鲸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)闷叉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人脊阴,你說(shuō)我怎么就攤上這事握侧。” “怎么了嘿期?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵品擎,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我备徐,道長(zhǎng)萄传,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任蜜猾,我火速辦了婚禮秀菱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蹭睡。我一直安慰自己衍菱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布肩豁。 她就那樣靜靜地躺著脊串,像睡著了一般辫呻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上琼锋,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天印屁,我揣著相機(jī)與錄音,去河邊找鬼斩例。 笑死雄人,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的念赶。 我是一名探鬼主播础钠,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼叉谜!你這毒婦竟也來(lái)了旗吁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤停局,失蹤者是張志新(化名)和其女友劉穎很钓,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體董栽,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡码倦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锭碳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袁稽。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖擒抛,靈堂內(nèi)的尸體忽然破棺而出推汽,到底是詐尸還是另有隱情,我是刑警寧澤歧沪,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布歹撒,位于F島的核電站,受9級(jí)特大地震影響诊胞,放射性物質(zhì)發(fā)生泄漏暖夭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一厢钧、第九天 我趴在偏房一處隱蔽的房頂上張望鳞尔。 院中可真熱鬧,春花似錦早直、人聲如沸寥假。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)糕韧。三九已至枫振,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間萤彩,已是汗流浹背粪滤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雀扶,地道東北人杖小。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像愚墓,于是被迫代替她去往敵國(guó)和親予权。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • redis集群分為服務(wù)端集群和客戶端分片浪册,redis3.0以上版本實(shí)現(xiàn)了集群機(jī)制扫腺,即服務(wù)端集群,3.0以下使用客戶...
    hadoop_null閱讀 1,586評(píng)論 0 6
  • Redis Cluster介紹 redis cluster是Redis的分布式解決方案村象,在3.0版本推出后有效地解...
    dayspring閱讀 10,991評(píng)論 0 3
  • feisky云計(jì)算笆环、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,827評(píng)論 0 5
  • 1 redis概述 1.1 什么是redis ??Redis的全稱是REmote Dictionary Serve...
    一把君子劍閱讀 422評(píng)論 0 0
  • 夢(mèng)婆:“帥無(wú)棋,到你了厚者,這里有三種技能躁劣,你選擇一種吧!別說(shuō)我不給你機(jī)會(huì)籍救,念你百世無(wú)惡习绢,你可從心想事成、與世無(wú)爭(zhēng)蝙昙、九...
    天地緯城閱讀 128評(píng)論 0 0