1.一種基于Gossip通信協(xié)議和Raft選舉算法的優(yōu)化方法,是應(yīng)用于由N×(n+1)個(gè)節(jié)點(diǎn)組成的Redis集群中,所述節(jié)點(diǎn)是運(yùn)行在集群模式下的Redis服務(wù)器,并分為N個(gè)主節(jié)點(diǎn)和N×n個(gè)從節(jié)點(diǎn),任意一個(gè)主節(jié)點(diǎn)分別對(duì)應(yīng)于n個(gè)從節(jié)點(diǎn),由一個(gè)主節(jié)點(diǎn)及其對(duì)應(yīng)的n個(gè)從節(jié)點(diǎn)構(gòu)成一個(gè)分片;其特征是,所述優(yōu)化方法按如下步驟進(jìn)行:
步驟1、全局定義:
定義所述N個(gè)主節(jié)點(diǎn)構(gòu)成的主節(jié)點(diǎn)集合為{M1,M2,…,Mi,…,MN},Mi表示第i個(gè)主節(jié)點(diǎn);1≤i≤N;
定義所述第i個(gè)主節(jié)點(diǎn)Mi的從節(jié)點(diǎn)集合為{Si1,Si2,…,Sij,…,Sin},Sij表示第i個(gè)主節(jié)點(diǎn)Mi所對(duì)應(yīng)的第j個(gè)從節(jié)點(diǎn);1≤j≤n;
定義Redis集群中的所有節(jié)點(diǎn)集合為{N1,N2,…,Nk,…,NN×(n+1)},Nk表示第k個(gè)節(jié)點(diǎn),1≤k≤N×(n+1);
定義保存所述第k個(gè)節(jié)點(diǎn)Nk詳細(xì)狀態(tài)信息的結(jié)構(gòu)體為第k個(gè)狀態(tài)結(jié)構(gòu)體CNk;
定義保存并維護(hù)所述第k個(gè)節(jié)點(diǎn)Nk對(duì)Redis集群認(rèn)知的結(jié)構(gòu)體為第k個(gè)認(rèn)知結(jié)構(gòu)體CSk,所述第k個(gè)認(rèn)知結(jié)構(gòu)體CSk中所保存的信息包括:當(dāng)前紀(jì)元、上一次投票紀(jì)元和Redis集群中所有節(jié)點(diǎn)的狀態(tài)結(jié)構(gòu)體;定義第k個(gè)認(rèn)知結(jié)構(gòu)體CSk中的當(dāng)前紀(jì)元記為CEk、上一次投票紀(jì)元記為LEk、所有節(jié)點(diǎn)的狀態(tài)結(jié)構(gòu)體所組成的鏈表為NOk;
定義任意第p個(gè)節(jié)點(diǎn)Np和第q個(gè)節(jié)點(diǎn)Nq之間周期性的通信消息為PING/PONG消息;1≤p,q≤N×(n+1);p≠q;
所述第p個(gè)節(jié)點(diǎn)Np發(fā)送的PING/PONG消息中攜帶自身的狀態(tài)信息和相應(yīng)的Gossip單元;定義所述Gossip單元包含w條Gossip消息;每條Gossip消息對(duì)應(yīng)一個(gè)其他節(jié)點(diǎn)的狀態(tài)信息,通過Redis集群中的PING/PONG消息傳播,所述第p個(gè)節(jié)點(diǎn)Np更新自身的認(rèn)知結(jié)構(gòu)體CSp;
定義節(jié)點(diǎn)間的通信超時(shí)時(shí)間為T;
定義所述Redis集群中的所有節(jié)點(diǎn)分為三種狀態(tài),包括:在線狀態(tài)、疑似下線狀態(tài)、下線狀態(tài);
在線狀態(tài)表示第p個(gè)節(jié)點(diǎn)Np在發(fā)送PING消息后,在通信超時(shí)時(shí)間T內(nèi)收到接收第q個(gè)節(jié)點(diǎn)Nq的PONG消息,則第q個(gè)節(jié)點(diǎn)Nq認(rèn)為第p個(gè)節(jié)點(diǎn)Np處于在線狀態(tài);
疑似下線狀態(tài)表示第p個(gè)節(jié)點(diǎn)Np在發(fā)送PING消息后,在通信超時(shí)時(shí)間T內(nèi)沒有收到接收第q個(gè)節(jié)點(diǎn)Nq的PONG消息,則第p個(gè)節(jié)點(diǎn)Np認(rèn)為第q個(gè)節(jié)點(diǎn)Nq處于疑似下線狀態(tài);
下線狀態(tài)表示第p個(gè)節(jié)點(diǎn)Np發(fā)現(xiàn)超過個(gè)主節(jié)點(diǎn)認(rèn)為第q個(gè)節(jié)點(diǎn)Nq處于疑似下線狀態(tài),則第p個(gè)節(jié)點(diǎn)Np認(rèn)為第q個(gè)節(jié)點(diǎn)Nq處于下線狀態(tài),并將第q個(gè)節(jié)點(diǎn)Nq的下線消息廣播給其他節(jié)點(diǎn);
定義在Redis集群中第k個(gè)節(jié)點(diǎn)Nk的鏈表NOk中處于疑似下線狀態(tài)的節(jié)點(diǎn)數(shù)為uk;
定義選取次數(shù)為r,并初始化r=1;
步驟2、第k個(gè)節(jié)點(diǎn)Nk每秒鐘固定向其他m個(gè)接收節(jié)點(diǎn)發(fā)送PING消息;
步驟3、基于Gossip通信協(xié)議優(yōu)化方法對(duì)m的值和接收節(jié)點(diǎn)的選取方式進(jìn)行更改:
步驟3.1、令
步驟3.2、第k個(gè)節(jié)點(diǎn)Nk在Redis集群中未選取的節(jié)點(diǎn)內(nèi)第r次隨機(jī)選取一個(gè)預(yù)接收節(jié)點(diǎn),判斷所述預(yù)接收節(jié)點(diǎn)與第k個(gè)節(jié)點(diǎn)Nk之間中斷PING/PONG通信的時(shí)間是否超過T/2,若超過,則將所述預(yù)接收節(jié)點(diǎn)作為接收節(jié)點(diǎn);否則,丟棄所述預(yù)接收節(jié)點(diǎn);
步驟3.3、將r+1賦值給r,并返回步驟3.2執(zhí)行,直到r=m+1為止,從而獲得m1個(gè)接收節(jié)點(diǎn);
步驟3.4、判斷m1=m是否成立,若成立,則執(zhí)行步驟3.8,否則執(zhí)行步驟3.5;
步驟3.5、初始化r=1;
步驟3.6、第k個(gè)節(jié)點(diǎn)Nk在Redis集群中未選取的節(jié)點(diǎn)內(nèi)第r次隨機(jī)選取一個(gè)接收節(jié)點(diǎn);
步驟3.7、將r+1賦值給r,并返回步驟3.6執(zhí)行,直到r=m-m1+1為止,從而獲得m-m1個(gè)接收節(jié)點(diǎn);
步驟3.8、第k個(gè)節(jié)點(diǎn)Nk向m個(gè)接收節(jié)點(diǎn)發(fā)送PING消息;
步驟4、主節(jié)點(diǎn)M′故障后,第k個(gè)節(jié)點(diǎn)Nk向主節(jié)點(diǎn)M′發(fā)送PING消息,并在通信超時(shí)時(shí)間T內(nèi)未收到主節(jié)點(diǎn)M′的PONG消息,則第k個(gè)節(jié)點(diǎn)Nk認(rèn)為主節(jié)點(diǎn)M′處于疑似下線狀態(tài),并將所述主節(jié)點(diǎn)M′的狀態(tài)信息作為一條Gossip消息添加到PING/PONG消息的Gossip單元中,并發(fā)送給其他節(jié)點(diǎn),從而告知其他節(jié)點(diǎn)主節(jié)點(diǎn)M′處于疑似下線狀態(tài);
步驟5、通過PING/PONG消息的傳播,主節(jié)點(diǎn)M′的疑似下線消息會(huì)在Redis集群中擴(kuò)散,基于Gossip通信協(xié)議的優(yōu)化方法對(duì)w的值和Gossip單元的選取方式進(jìn)行更改:
步驟5.1、令wk=w+uk;
步驟5.2、第k個(gè)節(jié)點(diǎn)Nk標(biāo)記uk個(gè)處于疑似下線狀態(tài)的節(jié)點(diǎn),并將所述uk個(gè)節(jié)點(diǎn)的狀態(tài)信息優(yōu)先添加到自身PING/PONG消息的Gossip單元中;
步驟5.3、第k個(gè)節(jié)點(diǎn)Nk在未選取的節(jié)點(diǎn)中隨機(jī)選取w個(gè)節(jié)點(diǎn),并將所述w個(gè)節(jié)點(diǎn)的狀態(tài)信息優(yōu)先添加到自身PING/PONG消息的Gossip單元中;從而共選取w+uk個(gè)節(jié)點(diǎn)作為wk個(gè)Gossip消息添加到Gossip單元中;
步驟6、通過PING/PONG消息的傳播,第p個(gè)節(jié)點(diǎn)Np發(fā)現(xiàn)超過個(gè)主節(jié)點(diǎn)認(rèn)為主節(jié)點(diǎn)M′處于疑似下線狀態(tài),則第p個(gè)節(jié)點(diǎn)Np認(rèn)為主節(jié)點(diǎn)M′處于下線狀態(tài),并將主節(jié)點(diǎn)M′的下線消息廣播給其他節(jié)點(diǎn);從而使得主節(jié)點(diǎn)M′處于下線狀態(tài)的消息在Redis集群中傳播;
步驟7、假設(shè)發(fā)生故障的主節(jié)點(diǎn)M′所對(duì)應(yīng)的主節(jié)點(diǎn)為第i個(gè)主節(jié)點(diǎn)Mi;則當(dāng)從節(jié)點(diǎn)集合{Si1,Si2,…,Sij,…,Sin}接收到的PING/PONG消息中包含主節(jié)點(diǎn)M′處于下線狀態(tài)的信息時(shí),第j個(gè)從節(jié)點(diǎn)Sij向所有節(jié)點(diǎn)發(fā)起投票請(qǐng)求;
步驟8、第k個(gè)節(jié)點(diǎn)Nk接收到所述第j個(gè)從節(jié)點(diǎn)Sij的投票請(qǐng)求,則基于Raft選舉算法對(duì)投票方式進(jìn)行更改:
步驟8.1、第k個(gè)節(jié)點(diǎn)Nk將認(rèn)知結(jié)構(gòu)體CSk上的當(dāng)前紀(jì)元CEk和上一次投票紀(jì)元LEk保存到鏈表NOk的所有狀態(tài)結(jié)構(gòu)體中;從而使得所有狀態(tài)結(jié)構(gòu)體中均保存各自的當(dāng)前紀(jì)元和上一次投票紀(jì)元;
步驟8.2、若第k個(gè)節(jié)點(diǎn)Nk是主節(jié)點(diǎn),則獲得發(fā)生故障的主節(jié)點(diǎn)M′在所有節(jié)點(diǎn)中所在的位置z后,第k個(gè)節(jié)點(diǎn)Nk通過認(rèn)知結(jié)構(gòu)體CSk保存的第z個(gè)狀態(tài)結(jié)構(gòu)體CNz上的當(dāng)前紀(jì)元和上一次投票紀(jì)元來判斷是否發(fā)送支持票給第j個(gè)從節(jié)點(diǎn)Sij;若第k個(gè)節(jié)點(diǎn)Nk是從節(jié)點(diǎn),則第k個(gè)節(jié)點(diǎn)Nk對(duì)投票請(qǐng)求不做任何處理;
步驟9、當(dāng)?shù)趈個(gè)從節(jié)點(diǎn)Sij接收到個(gè)主節(jié)點(diǎn)的支持票時(shí),第j個(gè)從節(jié)點(diǎn)Sij升為新的主節(jié)點(diǎn),代替原來主節(jié)點(diǎn)的功能,并通過廣播PING消息告知所有的其他節(jié)點(diǎn),從而使得Redis集群中所有節(jié)點(diǎn)得知第j個(gè)從節(jié)點(diǎn)Sij升為主節(jié)點(diǎn);
步驟10、Redis集群恢復(fù)成功。