Raft協(xié)議簡(jiǎn)析

什么是Replicated state machines(復(fù)制狀態(tài)機(jī)):

一致性算法之所以可以保證在有節(jié)點(diǎn)掛掉時(shí)也能夠繼續(xù)服務(wù)革娄, 就是因?yàn)橛蠷eplicated state machines的存在晋南。 在分布式系統(tǒng)中蜈亩, 有兩種方式來實(shí)現(xiàn)這個(gè)復(fù)制狀態(tài)機(jī)

  1. 用一個(gè)專門節(jié)點(diǎn)負(fù)責(zé)記錄整個(gè)集群的元信息, 如HDFS暇务, GFS
  2. 每個(gè)節(jié)點(diǎn)都會(huì)記錄replicated log劣针,確保每個(gè)節(jié)點(diǎn)的log最終都包含了相同的請(qǐng)求, 并且是同樣的順序

一致性算法一般有一下特點(diǎn):

  1. 保證安全(不會(huì)返回錯(cuò)誤數(shù)據(jù))
  2. 只有半數(shù)以上的節(jié)點(diǎn)存活就可以繼續(xù)提供服務(wù)
  3. 不依賴時(shí)鐘來提供一致性押搪, 最多會(huì)造成不可用
  4. 通常只要半數(shù)以上節(jié)點(diǎn)完成請(qǐng)求就算成功树酪, 小部分慢節(jié)點(diǎn)不會(huì)影響整個(gè)系統(tǒng)的性能

為啥不用Paxos?

  1. 不清晰大州, 難以理解
  2. 不好實(shí)現(xiàn)续语, 只提供了single-decree Paxos的細(xì)節(jié), 沒有給出multi-Paxos的細(xì)節(jié)

Raft一致性算法

Raft算法首先會(huì)選舉一個(gè)leader厦画, 然后又leader來管理replicated log疮茄。 leader會(huì)從client處接收請(qǐng)求, 然后轉(zhuǎn)發(fā)給別的節(jié)點(diǎn)根暑, 并且告訴這些節(jié)點(diǎn)什么時(shí)候可以把這些請(qǐng)求應(yīng)用在狀態(tài)機(jī)上(落地)力试。 當(dāng)一個(gè)leader掛了的時(shí)候, 會(huì)馬上選舉出一個(gè)新的leader排嫌。 由上可知畸裳, Raft將一致性問題拆分成了3個(gè)獨(dú)立的子問題:

  1. Leader選舉
  2. 日志的復(fù)制(Log replication)
  3. Safty: 不能有錯(cuò)誤數(shù)據(jù)
  • Raft的實(shí)踐基礎(chǔ)
    一個(gè)Raft集群會(huì)有多個(gè)節(jié)點(diǎn), 一般至少5個(gè)躏率, 這樣可以忍受2個(gè)節(jié)點(diǎn)fail躯畴。 這些節(jié)點(diǎn)在任何時(shí)間點(diǎn)都會(huì)是以下3個(gè)狀態(tài)之一: leader民鼓, follower, candidate蓬抄。
    Raft將時(shí)間分為了多個(gè)term丰嘉, 選舉會(huì)產(chǎn)生一個(gè)新的term, 每個(gè)term的時(shí)長不定嚷缭,但是每個(gè)term都至多有一個(gè)leader
    不同的節(jié)點(diǎn)會(huì)在不同時(shí)間感知到變化饮亏,有些節(jié)點(diǎn)甚至在一個(gè)term完結(jié)時(shí)都沒有感知到。 Terms是一個(gè)邏輯時(shí)鐘阅爽, 每個(gè)節(jié)點(diǎn)都會(huì)存儲(chǔ)當(dāng)前term路幸, 并且會(huì)一直跟別的節(jié)點(diǎn)交換信息, 一旦發(fā)現(xiàn)自己的term不是最新的付翁, 就會(huì)更新term简肴, 如果一個(gè)candidate或者leader發(fā)現(xiàn)他的term過時(shí)了,就會(huì)馬上回退成follower百侧。 如果一個(gè)節(jié)點(diǎn)收到一個(gè)過期term的請(qǐng)求砰识, 那么他會(huì)拒絕這個(gè)請(qǐng)求
    Raft節(jié)點(diǎn)間通過RPC請(qǐng)求進(jìn)行通信, 基本的算法只要求兩種RPC請(qǐng)求類型佣渴。 一種是RequestVote RPCs, 由candidate在選舉時(shí)發(fā)出辫狼。 一種是AppendEntries RPCs, 由leader發(fā)出辛润, 用來復(fù)制log和發(fā)送心跳

  • leader選舉
    Raft用心跳來觸發(fā)leader選舉膨处, 當(dāng)節(jié)點(diǎn)啟動(dòng)時(shí), 都是follower的狀態(tài)砂竖。只要節(jié)點(diǎn)能夠收到來自leader或者candidate的RPC真椿, 節(jié)點(diǎn)就會(huì)保持follower狀態(tài)。
    Leader會(huì)定期發(fā)送RPC給所有的follower來維持他的leader地位乎澄, 但是一旦有一個(gè)節(jié)點(diǎn)在一段時(shí)間沒有收到心跳瀑粥, 那么節(jié)點(diǎn)就會(huì)認(rèn)為沒有存活的leader并且觸發(fā)新一次的選舉。
    選舉開始時(shí)三圆,一個(gè)follower會(huì)給當(dāng)前term加1并且轉(zhuǎn)換成candidate狀態(tài)。 然后這個(gè)節(jié)點(diǎn)會(huì)給自己投票并且給所有其他節(jié)點(diǎn)發(fā)送RequestVote RPC避咆。
    Candidate會(huì)保持這個(gè)狀態(tài)直到以下3個(gè)事件中的一個(gè)發(fā)生:

    1. 這個(gè)節(jié)點(diǎn)贏得選舉
      如果這個(gè)節(jié)點(diǎn)贏得了半數(shù)以上的vote就會(huì)成為leader舟肉,每個(gè)節(jié)點(diǎn)會(huì)按照first-come-first-served的原則進(jìn)行投票,并且一個(gè)term中只能投給一個(gè)節(jié)點(diǎn)查库, 這樣就保證了一個(gè)term最多有一個(gè)節(jié)點(diǎn)贏得半數(shù)以上的vote路媚。
      當(dāng)一個(gè)節(jié)點(diǎn)贏得選舉, 他會(huì)成為leader樊销, 并且給所有節(jié)點(diǎn)發(fā)送這個(gè)信息整慎, 這樣所有節(jié)點(diǎn)都會(huì)回退成follower脏款。
    2. 另外一個(gè)節(jié)點(diǎn)贏得選舉
      在等待vote時(shí), 如果這個(gè)candidate收到了別的節(jié)點(diǎn)請(qǐng)求vote的RPC裤园, 那么他會(huì)檢查是否這個(gè)節(jié)點(diǎn)的term大于等于自己的term撤师, 如果是那么這個(gè)candidate就會(huì)回退成follower。 如果不是就會(huì)reject這個(gè)RPC拧揽。
    3. 一個(gè)選舉周期結(jié)束并且沒有l(wèi)eader選出來
      這種情況是由于可能有很多follower都成為了candidate剃盾, 那么vote就會(huì)很分散, 最后沒有一個(gè)節(jié)點(diǎn)拿到半數(shù)以上的vote淤袜。最后這個(gè)term超時(shí)并且進(jìn)入下個(gè)term繼續(xù)選舉痒谴。
      為了防止這種情況一直重復(fù),每個(gè)節(jié)點(diǎn)的election 超時(shí)時(shí)間是(150~300ms)的隨機(jī)數(shù)铡羡, 這樣在一個(gè)term就會(huì)有一個(gè)節(jié)點(diǎn)很快超時(shí)進(jìn)入下一個(gè)term积蔚, 然后就能在別的節(jié)點(diǎn)timeout之前贏得選舉
Figure3
  • Log replication
    當(dāng)leader選出來后,他就可以正式給客戶端提供服務(wù)烦周。 leader會(huì)將請(qǐng)求以entry的形式追加到自己的log中尽爆,并且將這個(gè)entry以AppendEntries RPC并發(fā)發(fā)送給所有的follower節(jié)點(diǎn)。 當(dāng)這個(gè)entry成功的復(fù)制后(怎么算成功之后會(huì)談到)论矾, leader會(huì)將這個(gè)entry 應(yīng)用到自己的state machine并且給client返回成功教翩。 如果復(fù)制失敗, leader會(huì)一直重試AppendEntries RPC直到所有l(wèi)og entry都被成功復(fù)制贪壳。
Logs Organization

Logs 組織的形式如圖所示饱亿。 當(dāng)leader收到一個(gè)Log entry時(shí), 每個(gè)log entry都會(huì)存儲(chǔ)一個(gè)帶有term number的state machine命令闰靴。 Term number是用來探測(cè)log之間的不一致性并且保證Figure3的一些特性彪笼。 每個(gè)log也還帶有他們?cè)趌og里的索引數(shù)字。

當(dāng)leader認(rèn)為這個(gè)entry是可以成功應(yīng)用到狀態(tài)機(jī)上蚂且, 那么這個(gè)entry就被成為commited配猫。Raft保證所有commited entry最終都會(huì)被應(yīng)用到所有的節(jié)點(diǎn)上。

當(dāng)一個(gè)entry被成功復(fù)制到半數(shù)以上的節(jié)點(diǎn)后杏死, 這個(gè)log就可以認(rèn)為成功寫入了泵肄。并且會(huì)將leader之前的寫入也視為commit。

設(shè)計(jì)Raft日志機(jī)制不僅簡(jiǎn)化了系統(tǒng)的行為淑翼, 也保證了正確性腐巢。 保證了Figure3的以下特性
1. 當(dāng)不同log中的兩個(gè)entry有相同的term和index, 那么這兩個(gè)entry就是相同的
2. 當(dāng)不同log中的兩個(gè)entry有相同的term和index玄括, 那么這兩個(gè)entry之前的所有entry也都是相同的

Paste_Image.png

當(dāng)leader發(fā)現(xiàn)follower的log跟自己的不同時(shí)冯丙, 他會(huì)針對(duì)每個(gè)follower維護(hù)一個(gè)nextIndex。 這個(gè)nextIndex就是Leader下次會(huì)發(fā)第幾個(gè)entry給這個(gè)follower遭京。 而follower也會(huì)拒絕這個(gè)append entry的rpc胃惜。

Safety

  • 如何保證數(shù)據(jù)不丟失和數(shù)據(jù)的正確性是分布式數(shù)據(jù)庫最重要的兩點(diǎn)泞莉, Raft協(xié)議也設(shè)計(jì)了相應(yīng)的算法來保證這兩點(diǎn)。
    1. 所有的entry都只能從leader流向follower船殉,而要成為leader必須有所有的committed entries鲫趁。 如果有server發(fā)現(xiàn)candidate的數(shù)據(jù)沒有自己更update-to-date, 那么他會(huì)拒絕這個(gè)vote request。 如果兩個(gè)server的log term不同捺弦, 那么term number更大的更update-to-date, 如果term相同饮寞, 那么index更大的更update-to-date。
Figure 3
  1. 僅有第一點(diǎn)的保證我們?nèi)耘f可能會(huì)遇到問題列吼。 如上圖所示幽崩, a) s1成為leader,部分拷貝了index 2; b) s1掛了寞钥, s5成為leader, 寫入index 3; c)s5又掛了慌申, s1再次成為leader并且繼續(xù)將index 2拷貝到其余follower; d) s1又一次掛了理郑, s5成為leader(獲得2,3,4的選票)蹄溉, 將自己所有的s3拷貝到別的機(jī)器并且覆蓋掉了index 2; e)如果c階段沒有掛那么日志會(huì)被拷貝到s2,s3, 之后s5就不會(huì)被選為leader。
    上圖演示了寫入數(shù)據(jù)可能會(huì)被覆蓋的問題您炉, 那么如何避免這個(gè)問題柒爵。 Raft規(guī)定絕不通過計(jì)算副本數(shù)的方式commit 之前term的log entries。 只有當(dāng)前term的log enties使用計(jì)算副本的方式來提交赚爵。 對(duì)于之前的term來說棉胀,當(dāng)一個(gè)log通過這個(gè)方式提交成功了,那么他之前的所有l(wèi)og都算commit成功了冀膝。

    如何證明這個(gè)結(jié)論的正確性唁奢, 論文用反證法進(jìn)行了論證:

Figure 4

如Figure 4所示, 如果term T commit的數(shù)據(jù)在之后的term U丟失了窝剖, 那么
1. 這個(gè)log一定不在Leader-U的log中(因?yàn)閘eader不會(huì)覆蓋舊數(shù)據(jù))
2. Leader-T把這個(gè)日志復(fù)制給了大多數(shù)節(jié)點(diǎn)并且Leader-U收到了大多數(shù)節(jié)點(diǎn)的投票麻掸, 所以至少有一個(gè)節(jié)點(diǎn)是既收到了這個(gè)entry并且又給Leader-U投票了
3. 那么這個(gè)投票的節(jié)點(diǎn)也一定收到了所有Leader-T的commited entries
4. 因?yàn)檫@個(gè)投票節(jié)點(diǎn)把票投給了U, 那么說明Leader-U也至少有所有這個(gè)節(jié)點(diǎn)的entries
由此可知, 如果投票節(jié)點(diǎn)和Leader-U 共享了之前的log赐纱, 那么Leader-U肯定會(huì)有所有投票節(jié)點(diǎn)的entry脊奋。 另外, Leader-U的last-log-term必須比T大疙描, 而投票節(jié)點(diǎn)的term至少是T狂魔。之前term的leader在復(fù)制entry給Leader-U時(shí)也必須包含了之前的這個(gè)entry。 投票節(jié)點(diǎn)和之前term的leader都會(huì)有這個(gè)entry淫痰, 所以Leader-U也不會(huì)沒有這個(gè)entry≌荩可下結(jié)論所有大于T的term的leader絕對(duì)包含了所有term T commited的entries待错。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末籽孙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子火俄,更是在濱河造成了極大的恐慌犯建,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓜客,死亡現(xiàn)場(chǎng)離奇詭異适瓦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谱仪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門玻熙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人疯攒,你說我怎么就攤上這事嗦随。” “怎么了敬尺?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵枚尼,是天一觀的道長。 經(jīng)常有香客問我砂吞,道長署恍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任蜻直,我火速辦了婚禮盯质,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘袭蝗。我一直安慰自己唤殴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布到腥。 她就那樣靜靜地躺著朵逝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乡范。 梳的紋絲不亂的頭發(fā)上配名,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音晋辆,去河邊找鬼渠脉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瓶佳,可吹牛的內(nèi)容都是我干的芋膘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼为朋!你這毒婦竟也來了臂拓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤习寸,失蹤者是張志新(化名)和其女友劉穎胶惰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霞溪,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡孵滞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鸯匹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坊饶。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖忽你,靈堂內(nèi)的尸體忽然破棺而出幼东,到底是詐尸還是另有隱情,我是刑警寧澤科雳,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布根蟹,位于F島的核電站,受9級(jí)特大地震影響糟秘,放射性物質(zhì)發(fā)生泄漏简逮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一尿赚、第九天 我趴在偏房一處隱蔽的房頂上張望散庶。 院中可真熱鬧,春花似錦凌净、人聲如沸悲龟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽须教。三九已至,卻和暖如春斩芭,著一層夾襖步出監(jiān)牢的瞬間轻腺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工划乖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贬养,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓琴庵,卻偏偏與公主長得像误算,于是被迫代替她去往敵國和親仰美。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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