Raft 算法(詳細(xì)版)

1. Raft 算法簡介

1.1 Raft 背景

在分布式系統(tǒng)中谅辣,一致性算法至關(guān)重要彰亥。在所有一致性算法中哥童,Paxos 最負(fù)盛名祟霍,它由萊斯利·蘭伯特(Leslie Lamport)于 1990 年提出速缨,是一種基于消息傳遞的一致性算法锌妻,被認(rèn)為是類似算法中最有效的。

Paxos 算法雖然很有效旬牲,但復(fù)雜的原理使它實(shí)現(xiàn)起來非常困難仿粹,截止目前,實(shí)現(xiàn) Paxos 算法的開源軟件很少原茅,比較出名的有 Chubby吭历、LibPaxos。此外员咽,Zookeeper 采用的 ZAB(Zookeeper Atomic Broadcast)協(xié)議也是基于 Paxos 算法實(shí)現(xiàn)的毒涧,不過 ZAB 對(duì) Paxos 進(jìn)行了很多改進(jìn)與優(yōu)化,兩者的設(shè)計(jì)目標(biāo)也存在差異——ZAB 協(xié)議主要用于構(gòu)建一個(gè)高可用的分布式數(shù)據(jù)主備系統(tǒng)贝室,而 Paxos 算法則是用于構(gòu)建一個(gè)分布式的一致性狀態(tài)機(jī)系統(tǒng)契讲。

由于 Paxos 算法過于復(fù)雜、實(shí)現(xiàn)困難滑频,極大地制約了其應(yīng)用捡偏,而分布式系統(tǒng)領(lǐng)域又亟需一種高效而易于實(shí)現(xiàn)的分布式一致性算法,在此背景下峡迷,Raft 算法應(yīng)運(yùn)而生银伟。

Raft 算法在斯坦福 Diego Ongaro 和 John Ousterhout 于 2013 年發(fā)表的《In Search of an Understandable Consensus Algorithm》中提出。相較于 Paxos绘搞,Raft 通過邏輯分離使其更容易理解和實(shí)現(xiàn)彤避,目前,已經(jīng)有十多種語言的 Raft 算法實(shí)現(xiàn)框架夯辖,較為出名的有 etcd吞歼、Consul 淆储。

1.2 Raft 角色

根據(jù)官方文檔解釋,一個(gè) Raft 集群包含若干節(jié)點(diǎn),Raft 把這些節(jié)點(diǎn)分為三種狀態(tài):Leader杖玲、 Follower抡谐、Candidate铁追,每種狀態(tài)負(fù)責(zé)的任務(wù)也是不一樣的姻成。正常情況下,集群中的節(jié)點(diǎn)只存在 Leader 與 Follower 兩種狀態(tài)昙楚。

? Leader(領(lǐng)導(dǎo)者) :負(fù)責(zé)日志的同步管理近速,處理來自客戶端的請(qǐng)求,與Follower保持heartBeat的聯(lián)系;

? Follower(追隨者) :響應(yīng) Leader 的日志同步請(qǐng)求数焊,響應(yīng)Candidate的邀票請(qǐng)求永淌,以及把客戶端請(qǐng)求到Follower的事務(wù)轉(zhuǎn)發(fā)(重定向)給Leader;

? Candidate(候選者) :負(fù)責(zé)選舉投票佩耳,集群剛啟動(dòng)或者Leader宕機(jī)時(shí)遂蛀,狀態(tài)為Follower的節(jié)點(diǎn)將轉(zhuǎn)為Candidate并發(fā)起選舉,選舉勝出(獲得超過半數(shù)節(jié)點(diǎn)的投票)后干厚,從Candidate轉(zhuǎn)為Leader狀態(tài)李滴。

1.3 Raft 三個(gè)子問題

通常,Raft 集群中只有一個(gè) Leader蛮瞄,其它節(jié)點(diǎn)都是 Follower所坯。Follower 都是被動(dòng)的,不會(huì)發(fā)送任何請(qǐng)求挂捅,只是簡單地響應(yīng)來自 Leader 或者 Candidate 的請(qǐng)求芹助。Leader 負(fù)責(zé)處理所有的客戶端請(qǐng)求(如果一個(gè)客戶端和 Follower 聯(lián)系,那么 Follower 會(huì)把請(qǐng)求重定向給 Leader)闲先。

為簡化邏輯和實(shí)現(xiàn)状土,Raft 將一致性問題分解成了三個(gè)相對(duì)獨(dú)立的子問題。

? 選舉(Leader Election) :當(dāng) Leader 宕機(jī)或者集群初創(chuàng)時(shí)伺糠,一個(gè)新的 Leader 需要被選舉出來蒙谓;

? 日志復(fù)制(Log Replication) :Leader 接收來自客戶端的請(qǐng)求并將其以日志條目的形式復(fù)制到集群中的其它節(jié)點(diǎn),并且強(qiáng)制要求其它節(jié)點(diǎn)的日志和自己保持一致训桶;

? 安全性(Safety) :如果有任何的服務(wù)器節(jié)點(diǎn)已經(jīng)應(yīng)用了一個(gè)確定的日志條目到它的狀態(tài)機(jī)中累驮,那么其它服務(wù)器節(jié)點(diǎn)不能在同一個(gè)日志索引位置應(yīng)用一個(gè)不同的指令。

2. Raft 算法之 Leader Election 原理

根據(jù) Raft 協(xié)議舵揭,一個(gè)應(yīng)用 Raft 協(xié)議的集群在剛啟動(dòng)時(shí)谤专,所有節(jié)點(diǎn)的狀態(tài)都是 Follower。由于沒有 Leader午绳,F(xiàn)ollowers 無法與 Leader 保持心跳(Heart Beat)毒租,因此,F(xiàn)ollowers 會(huì)認(rèn)為 Leader 已經(jīng)下線箱叁,進(jìn)而轉(zhuǎn)為 Candidate 狀態(tài)。然后惕医,Candidate 將向集群中其它節(jié)點(diǎn)請(qǐng)求投票耕漱,同意自己升級(jí)為 Leader。如果 Candidate 收到超過半數(shù)節(jié)點(diǎn)的投票(N/2 + 1)抬伺,它將獲勝成為 Leader螟够。

第一階段:所有節(jié)點(diǎn)都是 Follower。

上面提到,一個(gè)應(yīng)用 Raft 協(xié)議的集群在剛啟動(dòng)(或 Leader 宕機(jī))時(shí)妓笙,所有節(jié)點(diǎn)的狀態(tài)都是 Follower若河,初始 Term(任期)為 0。同時(shí)啟動(dòng)選舉定時(shí)器寞宫,每個(gè)節(jié)點(diǎn)的選舉定時(shí)器超時(shí)時(shí)間都在 100~500 毫秒之間且并不一致(避免同時(shí)發(fā)起選舉)萧福。

所有節(jié)點(diǎn)都是 Follower

第二階段:Follower 轉(zhuǎn)為 Candidate 并發(fā)起投票。

沒有 Leader辈赋,F(xiàn)ollowers 無法與 Leader 保持心跳(Heart Beat)鲫忍,節(jié)點(diǎn)啟動(dòng)后在一個(gè)選舉定時(shí)器周期內(nèi)未收到心跳和投票請(qǐng)求,則狀態(tài)轉(zhuǎn)為候選者 Candidate 狀態(tài)钥屈,且 Term 自增悟民,并向集群中所有節(jié)點(diǎn)發(fā)送投票請(qǐng)求并且重置選舉定時(shí)器。

注意篷就,由于每個(gè)節(jié)點(diǎn)的選舉定時(shí)器超時(shí)時(shí)間都在 100-500 毫秒之間射亏,且彼此不一樣,以避免所有 Follower 同時(shí)轉(zhuǎn)為 Candidate 并同時(shí)發(fā)起投票請(qǐng)求竭业。換言之智润,最先轉(zhuǎn)為 Candidate 并發(fā)起投票請(qǐng)求的節(jié)點(diǎn)將具有成為 Leader 的“先發(fā)優(yōu)勢(shì)”。

Follower 轉(zhuǎn)為 Candidate 并發(fā)起投票

第三階段:投票策略永品。

節(jié)點(diǎn)收到投票請(qǐng)求后會(huì)根據(jù)以下情況決定是否接受投票請(qǐng)求(每個(gè) follower 剛成為 Candidate 的時(shí)候會(huì)將票投給自己):

請(qǐng)求節(jié)點(diǎn)的 Term 大于自己的 Term做鹰,且自己尚未投票給其它節(jié)點(diǎn),則接受請(qǐng)求鼎姐,把票投給它钾麸;

請(qǐng)求節(jié)點(diǎn)的 Term 小于自己的 Term,且自己尚未投票炕桨,則拒絕請(qǐng)求饭尝,將票投給自己。

投票策略

第四階段:Candidate 轉(zhuǎn)為 Leader献宫。

一輪選舉過后钥平,正常情況下,會(huì)有一個(gè) Candidate 收到超過半數(shù)節(jié)點(diǎn)(N/2 + 1)的投票姊途,它將勝出并升級(jí)為 Leader涉瘾。然后定時(shí)發(fā)送心跳給其它的節(jié)點(diǎn),其它節(jié)點(diǎn)會(huì)轉(zhuǎn)為 Follower 并與 Leader 保持同步捷兰,到此立叛,本輪選舉結(jié)束。

注意:有可能一輪選舉中贡茅,沒有 Candidate 收到超過半數(shù)節(jié)點(diǎn)投票秘蛇,那么將進(jìn)行下一輪選舉其做。

Candidate 轉(zhuǎn)為 Leader

3. Raft 算法之 Log Replication 原理

在一個(gè) Raft 集群中,只有 Leader 節(jié)點(diǎn)能夠處理客戶端的請(qǐng)求(如果客戶端的請(qǐng)求發(fā)到了 Follower赁还,F(xiàn)ollower 將會(huì)把請(qǐng)求重定向到 Leader)妖泄,客戶端的每一個(gè)請(qǐng)求都包含一條被復(fù)制狀態(tài)機(jī)執(zhí)行的指令。Leader 把這條指令作為一條新的日志條目(Entry)附加到日志中去艘策,然后并行得將附加條目發(fā)送給 Followers蹈胡,讓它們復(fù)制這條日志條目。

當(dāng)這條日志條目被 Followers 安全復(fù)制柬焕,Leader 會(huì)將這條日志條目應(yīng)用到它的狀態(tài)機(jī)中审残,然后把執(zhí)行的結(jié)果返回給客戶端。如果 Follower 崩潰或者運(yùn)行緩慢斑举,再或者網(wǎng)絡(luò)丟包搅轿,Leader 會(huì)不斷得重復(fù)嘗試附加日志條目(盡管已經(jīng)回復(fù)了客戶端)直到所有的 Follower 都最終存儲(chǔ)了所有的日志條目,確保強(qiáng)一致性富玷。

第一階段:客戶端請(qǐng)求提交到 Leader璧坟。

如下圖所示,Leader 收到客戶端的請(qǐng)求赎懦,比如存儲(chǔ)數(shù)據(jù) 5雀鹃。Leader 在收到請(qǐng)求后,會(huì)將它作為日志條目(Entry)寫入本地日志中励两。需要注意的是黎茎,此時(shí)該 Entry 的狀態(tài)是未提交(Uncommitted),Leader 并不會(huì)更新本地?cái)?shù)據(jù)当悔,因此它是不可讀的傅瞻。

客戶端請(qǐng)求提交到 Leader

第二階段:Leader 將 Entry 發(fā)送到其它 Follower

Leader 與 Followers 之間保持著心跳聯(lián)系,隨心跳 Leader 將追加的 Entry(AppendEntries)并行地發(fā)送給其它的 Follower盲憎,并讓它們復(fù)制這條日志條目嗅骄,這一過程稱為復(fù)制(Replicate)。

有幾點(diǎn)需要注意:

1. 為什么 Leader 向 Follower 發(fā)送的 Entry 是 AppendEntries 呢饼疙?

因?yàn)?Leader 與 Follower 的心跳是周期性的溺森,而一個(gè)周期間 Leader 可能接收到多條客戶端的請(qǐng)求,因此窑眯,隨心跳向 Followers 發(fā)送的大概率是多個(gè) Entry屏积,即 AppendEntries。當(dāng)然磅甩,在本例中炊林,我們假設(shè)只有一條請(qǐng)求,自然也就是一個(gè)Entry了更胖。

2. Leader 向 Followers 發(fā)送的不僅僅是追加的 Entry(AppendEntries)。

在發(fā)送追加日志條目的時(shí)候,Leader 會(huì)把新的日志條目緊接著之前條目的索引位置(prevLogIndex)却妨, Leader 任期號(hào)(Term)也包含在其中饵逐。如果 Follower 在它的日志中找不到包含相同索引位置和任期號(hào)的條目,那么它就會(huì)拒絕接收新的日志條目彪标,因?yàn)槌霈F(xiàn)這種情況說明 Follower 和 Leader 不一致倍权。

3. 如何解決 Leader 與 Follower 不一致的問題?

在正常情況下捞烟,Leader 和 Follower 的日志保持一致薄声,所以追加日志的一致性檢查從來不會(huì)失敗。然而题画,Leader 和 Follower 一系列崩潰的情況會(huì)使它們的日志處于不一致狀態(tài)默辨。Follower可能會(huì)丟失一些在新的 Leader 中有的日志條目,它也可能擁有一些 Leader 沒有的日志條目苍息,或者兩者都發(fā)生缩幸。丟失或者多出日志條目可能會(huì)持續(xù)多個(gè)任期。

要使 Follower 的日志與 Leader 恢復(fù)一致竞思,Leader 必須找到最后兩者達(dá)成一致的地方(說白了就是回溯表谊,找到兩者最近的一致點(diǎn)),然后刪除從那個(gè)點(diǎn)之后的所有日志條目盖喷,發(fā)送自己的日志給 Follower爆办。所有的這些操作都在進(jìn)行附加日志的一致性檢查時(shí)完成。

Leader 為每一個(gè) Follower 維護(hù)一個(gè) nextIndex课梳,它表示下一個(gè)需要發(fā)送給 Follower 的日志條目的索引地址距辆。當(dāng)一個(gè) Leader 剛獲得權(quán)力的時(shí)候,它初始化所有的 nextIndex 值惦界,為自己的最后一條日志的 index 加 1挑格。如果一個(gè) Follower 的日志和 Leader 不一致,那么在下一次附加日志時(shí)一致性檢查就會(huì)失敗沾歪。在被 Follower 拒絕之后漂彤,Leader 就會(huì)減小該 Follower 對(duì)應(yīng)的 nextIndex 值并進(jìn)行重試。最終 nextIndex 會(huì)在某個(gè)位置使得 Leader 和 Follower 的日志達(dá)成一致灾搏。當(dāng)這種情況發(fā)生挫望,附加日志就會(huì)成功,這時(shí)就會(huì)把 Follower 沖突的日志條目全部刪除并且加上 Leader 的日志狂窑。一旦附加日志成功媳板,那么 Follower 的日志就會(huì)和 Leader 保持一致,并且在接下來的任期繼續(xù)保持一致泉哈。

如何解決 Leader 與 Follower 不一致的問題

第三階段:Leader 等待 Followers 回應(yīng)蛉幸。

Followers 接收到 Leader 發(fā)來的復(fù)制請(qǐng)求后破讨,有兩種可能的回應(yīng):

寫入本地日志中,返回 Success奕纫;

一致性檢查失敗提陶,拒絕寫入,返回 False匹层,原因和解決辦法上面已做了詳細(xì)說明隙笆。

需要注意的是,此時(shí)該 Entry 的狀態(tài)也是未提交(Uncommitted)升筏。完成上述步驟后撑柔,F(xiàn)ollowers 會(huì)向 Leader 發(fā)出 Success 的回應(yīng),當(dāng) Leader 收到大多數(shù) Followers 的回應(yīng)后您访,會(huì)將第一階段寫入的 Entry 標(biāo)記為提交狀態(tài)(Committed)铅忿,并把這條日志條目應(yīng)用到它的狀態(tài)機(jī)中。

Leader 等待 Followers 回應(yīng)

第四階段:Leader 回應(yīng)客戶端洋只。

完成前三個(gè)階段后辆沦,Leader會(huì)向客戶端回應(yīng) OK,表示寫操作成功识虚。

Leader 回應(yīng)客戶端

第五階段肢扯,Leader 通知 Followers Entry 已提交

Leader 回應(yīng)客戶端后,將隨著下一個(gè)心跳通知 Followers担锤,F(xiàn)ollowers 收到通知后也會(huì)將 Entry 標(biāo)記為提交狀態(tài)蔚晨。至此,Raft 集群超過半數(shù)節(jié)點(diǎn)已經(jīng)達(dá)到一致狀態(tài)肛循,可以確保強(qiáng)一致性铭腕。

需要注意的是,由于網(wǎng)絡(luò)多糠、性能累舷、故障等各種原因?qū)е隆胺磻?yīng)慢”、“不一致”等問題的節(jié)點(diǎn)夹孔,最終也會(huì)與 Leader 達(dá)成一致被盈。

Leader 通知 Followers Entry 已提交

4. Raft 算法之安全性

前面描述了 Raft 算法是如何選舉 Leader 和復(fù)制日志的。然而搭伤,到目前為止描述的機(jī)制并不能充分地保證每一個(gè)狀態(tài)機(jī)會(huì)按照相同的順序執(zhí)行相同的指令只怎。例如,一個(gè) Follower 可能處于不可用狀態(tài)怜俐,同時(shí) Leader 已經(jīng)提交了若干的日志條目身堡;然后這個(gè) Follower 恢復(fù)(尚未與 Leader 達(dá)成一致)而 Leader 故障;如果該 Follower 被選舉為 Leader 并且覆蓋這些日志條目拍鲤,就會(huì)出現(xiàn)問題贴谎,即不同的狀態(tài)機(jī)執(zhí)行不同的指令序列汞扎。

鑒于此,在 Leader 選舉的時(shí)候需增加一些限制來完善 Raft 算法擅这。這些限制可保證任何的 Leader 對(duì)于給定的任期號(hào)(Term)佩捞,都擁有之前任期的所有被提交的日志條目(所謂 Leader 的完整特性)。關(guān)于這一選舉時(shí)的限制蕾哟,下文將詳細(xì)說明。

4.1 選舉限制

在所有基于 Leader 機(jī)制的一致性算法中莲蜘,Leader 都必須存儲(chǔ)所有已經(jīng)提交的日志條目谭确。為了保障這一點(diǎn),Raft 使用了一種簡單而有效的方法票渠,以保證所有之前的任期號(hào)中已經(jīng)提交的日志條目在選舉的時(shí)候都會(huì)出現(xiàn)在新的 Leader 中逐哈。換言之,日志條目的傳送是單向的问顷,只從 Leader 傳給 Follower昂秃,并且 Leader 從不會(huì)覆蓋自身本地日志中已經(jīng)存在的條目。

Raft 使用投票的方式來阻止一個(gè) Candidate 贏得選舉杜窄,除非這個(gè) Candidate 包含了所有已經(jīng)提交的日志條目肠骆。Candidate 為了贏得選舉必須聯(lián)系集群中的大部分節(jié)點(diǎn)。這意味著每一個(gè)已經(jīng)提交的日志條目肯定存在于至少一個(gè)服務(wù)器節(jié)點(diǎn)上塞耕。如果 Candidate 的日志至少和大多數(shù)的服務(wù)器節(jié)點(diǎn)一樣新(這個(gè)新的定義會(huì)在下面討論)蚀腿,那么它一定持有了所有已經(jīng)提交的日志條目(多數(shù)派的思想)。投票請(qǐng)求的限制中請(qǐng)求中包含了 Candidate 的日志信息扫外,然后投票人會(huì)拒絕那些日志沒有自己新的投票請(qǐng)求莉钙。

Raft 通過比較兩份日志中最后一條日志條目的索引值和任期號(hào),確定誰的日志比較新筛谚。如果兩份日志最后條目的任期號(hào)不同磁玉,那么任期號(hào)大的日志更加新。如果兩份日志最后的條目任期號(hào)相同驾讲,那么日志比較長的那個(gè)就更加新蚊伞。

4.2 提交之前任期內(nèi)的日志條目

如同 4.1 節(jié)介紹的那樣,Leader 知道一條當(dāng)前任期內(nèi)的日志記錄是可以被提交的蝎毡,只要它被復(fù)制到了大多數(shù)的 Follower 上(多數(shù)派的思想)厚柳。如果一個(gè) Leader 在提交日志條目之前崩潰了,繼任的 Leader 會(huì)繼續(xù)嘗試復(fù)制這條日志記錄沐兵。然而别垮,一個(gè) Leader 并不能斷定被保存到大多數(shù) Follower 上的一個(gè)之前任期里的日志條目 就一定已經(jīng)提交了。這很明顯扎谎,從日志復(fù)制的過程可以看出碳想。

鑒于上述情況烧董,Raft 算法不會(huì)通過計(jì)算副本數(shù)目的方式去提交一個(gè)之前任期內(nèi)的日志條目。只有 Leader 當(dāng)前任期里的日志條目通過計(jì)算副本數(shù)目可以被提交胧奔;一旦當(dāng)前任期的日志條目以這種方式被提交逊移,那么由于日志匹配特性,之前的日志條目也都會(huì)被間接的提交龙填。在某些情況下胳泉,Leader 可以安全地知道一個(gè)老的日志條目是否已經(jīng)被提交(只需判斷該條目是否存儲(chǔ)到所有節(jié)點(diǎn)上),但是 Raft 為了簡化問題使用了一種更加保守的方法岩遗。

當(dāng) Leader 復(fù)制之前任期里的日志時(shí)扇商,Raft 會(huì)為所有日志保留原始的任期號(hào),這在提交規(guī)則上產(chǎn)生了額外的復(fù)雜性宿礁。但是案铺,這種策略更加容易辨別出日志,即使隨著時(shí)間和日志的變化梆靖,日志仍維護(hù)著同一個(gè)任期編號(hào)控汉。此外,該策略使得新 Leader 只需要發(fā)送較少日志條目返吻。

5姑子、線性化語義

raft 的讀寫都在 leader 節(jié)點(diǎn)中進(jìn)行,它保證了讀的都是最新的值测僵,它是符合強(qiáng)一致性的(線性一致性)壁酬,raft 除了這個(gè)還在【客戶端交互】那塊也做了一些保證,詳情可以參考論文恨课。但是 zookeeper 不同舆乔,zookeeper 寫在 leader,讀可以在 follower 進(jìn)行剂公,可能會(huì)讀到了舊值希俩,它不符合強(qiáng)一致性(只考慮寫一致性,不考慮讀一致性)纲辽,但是 zookeeper 去 follower 讀可以有效提升讀取的效率颜武。

6、后記

對(duì)比于 zab拖吼、raft鳞上,我們發(fā)現(xiàn)他們選舉、setData 都是需要過半機(jī)制才行吊档,所以他們針對(duì)網(wǎng)絡(luò)分區(qū)的處理方法都是一樣的篙议。

一個(gè)集群的節(jié)點(diǎn)經(jīng)過網(wǎng)絡(luò)分區(qū)后,如一共有 A、B鬼贱、C移怯、D、E 5個(gè)節(jié)點(diǎn)这难,如果 A 是 leader舟误,網(wǎng)絡(luò)分區(qū)為 A、B姻乓、C 和 D嵌溢、E,在A蹋岩、B堵腹、C分區(qū)還是能正常提供服務(wù)的,而在 D星澳、E 分區(qū)因?yàn)椴荒艿玫酱蠖鄶?shù)成員確認(rèn)(雖然分區(qū)了,但是因?yàn)榕渲玫脑蛩麄冞€是能知道所有的成員數(shù)量旱易,比如 zk 集群啟動(dòng)前需要配置所有成員地址禁偎,raft 也一樣),是不能進(jìn)行選舉的阀坏,所以保證只會(huì)有一個(gè) leader如暖。

如果分區(qū)為 A、B 和 C忌堂、D盒至、E ,A士修、B 分區(qū)雖然 A 還是 leader枷遂,但是卻不能提供事務(wù)服務(wù)(setData),C棋嘲、D酒唉、E 分區(qū)能重新選出 leader,還是能正常向外提供服務(wù)沸移。

7痪伦、后記2

1)我們所說的日志(log)與狀態(tài)機(jī)(state machine)不是一回事,日志指還沒有提交到狀態(tài)機(jī)中的數(shù)據(jù)雹锣。
2)新 leader 永遠(yuǎn)不會(huì)通過計(jì)算副本數(shù)量提交舊日志网沾,他只能復(fù)制舊日志都其他 follower 上,對(duì)于舊日志的提交蕊爵,只能是新 leader 接收新的寫請(qǐng)求寫新日志辉哥,順帶著把舊日志提交了。

8攒射、后記3

為什么采取隨機(jī)超時(shí)時(shí)間變成 candidate 獲取選票证薇,是為了防止導(dǎo)致沒有任何一個(gè) Candidate 選票數(shù)超過一半的情況重復(fù)循環(huán)發(fā)生度苔。比如有 3 個(gè) Candidate ,都得不到多數(shù)選票浑度,指的是都同時(shí)變成 candidate 然后都投給自己寇窑,然后都不會(huì)投給別人(如果日志都相同的情況下,如果自己日志落后于別人或者任期落后于別人箩张,自己就會(huì) stepDown甩骏,選票清空角色變成 follower)。然而其中某個(gè) Candidate C1 超時(shí)短先慷,立刻重新開始新的選舉饮笛,那么基本上就可以平定局勢(shì)了。注意论熙,此時(shí)另外兩個(gè) Candidate C2 和 Candidate C3 雖然也處于 Candidate 狀態(tài)福青,但是收到了 Candidate C1 的競選請(qǐng)求,并且發(fā)現(xiàn) C1 的任期號(hào)比自己大脓诡,會(huì)立刻變?yōu)?Follower 无午,并且投票給 C1 。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末祝谚,一起剝皮案震驚了整個(gè)濱河市宪迟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌交惯,老刑警劉巖次泽,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異席爽,居然都是意外死亡意荤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門只锻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來袭异,“玉大人,你說我怎么就攤上這事炬藤∮澹” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵沈矿,是天一觀的道長上真。 經(jīng)常有香客問我,道長羹膳,這世上最難降的妖魔是什么睡互? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上就珠,老公的妹妹穿的比我還像新娘寇壳。我一直安慰自己,他們只是感情好妻怎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布壳炎。 她就那樣靜靜地躺著,像睡著了一般逼侦。 火紅的嫁衣襯著肌膚如雪匿辩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天榛丢,我揣著相機(jī)與錄音铲球,去河邊找鬼。 笑死晰赞,一個(gè)胖子當(dāng)著我的面吹牛稼病,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掖鱼,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼然走,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了锨用?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤隘谣,失蹤者是張志新(化名)和其女友劉穎增拥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寻歧,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡掌栅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了码泛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猾封。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖噪珊,靈堂內(nèi)的尸體忽然破棺而出晌缘,到底是詐尸還是另有隱情,我是刑警寧澤痢站,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布磷箕,位于F島的核電站,受9級(jí)特大地震影響阵难,放射性物質(zhì)發(fā)生泄漏岳枷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望空繁。 院中可真熱鬧殿衰,春花似錦、人聲如沸盛泡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饭于。三九已至蜀踏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掰吕,已是汗流浹背果覆。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留殖熟,地道東北人局待。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像菱属,于是被迫代替她去往敵國和親钳榨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

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