理解raft(2) 日志復(fù)制

Raft保證的safety

Leader Append-Only:leader從來不覆寫或者刪除日志英岭,只會追加新日志俄占。

Log Matching:如果兩個主機的副本上的日志文件中萝招,包含一條相同term和log id的entry矾飞,那么奕塑,這兩個日志文件在這條日志之前的內(nèi)容都是相同的(字節(jié)流級別的一致)械姻。

Leader Completeness:如果一條日志已經(jīng)commit了,那么這條日志一定會出現(xiàn)在term最大的leader的日志文件中恩脂。

State Machine Safety:如果一個主機應(yīng)用了一條日志帽氓,那么,其他主機不可能應(yīng)用一條相同log id而內(nèi)容卻不同的日志俩块。

初選Leader后的日志同步

當一個新的Leader被選出來時黎休,它的日志和其它的Follower的日志可能不一樣,這個時候玉凯,就需要一個機制來保證日志的一致性势腮。

主備不一致可能有如下幾種情況:少了一些日志(term可能相同或者少了);多了一些未commit的日志(term可能多了也可能少了)漫仆;某些term多了一些日志且某些term少了一些日志捎拯。Raft中如何解決這些不一致呢?leader強制讓follower的日志文件復(fù)制leader的日志文件盲厌,即follower上不一致的日志文件內(nèi)容被覆寫

首先記住一個前提, raft選舉保證選出來得leader擁有最新最多commit的日志署照。

因此leader只需要知道follower缺哪些日志(確定最后一條相同的日志),就可以主動給follower同步所缺的日志吗浩,follower只要覆蓋掉不一致的部分即可建芙。

如何確定不一致的點?

leader維護一個log id懂扼,初始為leader本地最大的log id禁荸,然后發(fā)送AppendEntries RPC到follower,follower在收到AppendEntries之后阀湿,檢查RPC中攜帶的term和log id(leader上被追加的這條日志的前面一條日志的term和log id)赶熟,如果follower本地沒有這條日志,就拒絕此次AppendEntriesRPC陷嘴,leader就能知道follower的同步點更靠前映砖,逐漸就能知道同步點的位置。當然罩旋,實際實現(xiàn)時啊央,會使用更有效率的方法。

例如涨醋,當附加日志 RPC 的請求被拒絕的時候瓜饥,跟隨者可以包含沖突的條目的任期號和自己存儲的那個任期的最早的索引地址。借助這些信息浴骂,領(lǐng)導(dǎo)人可以減小 nextIndex 越過所有那個任期沖突的所有日志條目乓土;這樣就變成每個任期需要一次附加條目 RPC 而不是每個條目一次。在實踐中溯警,我們十分懷疑這種優(yōu)化是否是必要的趣苏,因為失敗是很少發(fā)生的并且也不大可能會有這么多不一致的日志。

image
  1. 在階段a梯轻,term為2食磕,S1是Leader,且S1寫入日志(term, index)為(2, 2)喳挑,并且日志被同步寫入了S2彬伦;

  2. 在階段b,S1離線伊诵,觸發(fā)一次新的選主单绑,此時S5被選為新的Leader,此時系統(tǒng)term為3曹宴,且寫入了日志(term, index)為(3搂橙, 2);

  3. S5尚未將日志推送到Followers變離線了,進而觸發(fā)了一次新的選主笛坦,而之前離線的S1經(jīng)過重新上線后被選中變成Leader区转,此時系統(tǒng)term為4,此時S1會將自己的日志同步到Followers版扩,按照上圖就是將日志(2蜗帜, 2)同步到了S3,而此時由于該日志已經(jīng)被同步到了多數(shù)節(jié)點(S1, S2, S3)资厉,因此厅缺,此時日志(2,2)可以被commit了(即更新到狀態(tài)機)宴偿;

  4. 在階段d湘捎,S1又很不幸地下線了,系統(tǒng)觸發(fā)一次選主窄刘,而S5有可能被選為新的Leader(這是因為S5可以滿足作為主的一切條件:1. term = 3 > 2, 2. 最新的日志index為2窥妇,比大多數(shù)節(jié)點(如S2/S3/S4的日志都新),然后S5會將自己的日志更新到Followers娩践,于是S2活翩、S3中已經(jīng)被提交的日志(2烹骨,2)被截斷了,這是致命性的錯誤材泄,因為一致性協(xié)議中不允許出現(xiàn)已經(jīng)應(yīng)用到狀態(tài)機中的日志被截斷沮焕。(論文描述)

這個問題的本質(zhì)是,S1上的term=2,log id=2的日志拉宗,在進行復(fù)制時峦树,使用的term仍然是term=2,而不是S1最新的term(4)旦事。在本地term較大的時候去復(fù)制term小的日志魁巩,這個是不合理的。但是為了維持Leader Append-Only的性質(zhì)姐浮,只能想辦法解決谷遂。

為了避免這種致命錯誤,需要對協(xié)議進行一個微調(diào):

只允許主節(jié)點提交包含當前term的日志

針對上述情況就是:即使日志(2卖鲤,2)已經(jīng)被大多數(shù)節(jié)點(S1埋凯、S2、S3)確認了扫尖,但是它不能被Commit白对,因為它是來自之前term(2)的日志,直到S1在當前term(4)產(chǎn)生的日志(4换怖, 3)被大多數(shù)Follower確認甩恼,S1方可Commit(4,3)這條日志.

commit的時候并不需要發(fā)給followers沉颂,commit就是回復(fù)client条摸。 leader只允許commit當前term的entry,其實是指積壓著之前已經(jīng)被majority認可的entry铸屉,直到當前term也被majority認可钉蒲,然后統(tǒng)一commit。

日志壓縮與快照

在實際的系統(tǒng)中彻坛,不能讓日志無限增長顷啼,否則系統(tǒng)重啟時需要花很長的時間進行回放,從而影響availability昌屉。Raft采用對整個系統(tǒng)進行snapshot來處理钙蒙,snapshot之前的日志都可以丟棄。Snapshot技術(shù)在Chubby和ZooKeeper系統(tǒng)中都有采用间驮。

Raft使用的方案是:每個副本獨立的對自己的系統(tǒng)狀態(tài)進行Snapshot躬厌,并且只能對已經(jīng)提交的日志記錄(已經(jīng)應(yīng)用到狀態(tài)機)進行snapshot。

Snapshot中包含以下內(nèi)容:

  • 日志元數(shù)據(jù)竞帽,最后一條commited log entry的 (log index, last_included_term)扛施。這兩個值在Snapshot之后的第一條log entry的AppendEntriesRPC的consistency check的時候會被用上鸿捧,之前講過。一旦這個server做完了snapshot疙渣,就可以把這條記錄的最后一條log index及其之前的所有的log entry都刪掉匙奴。

  • 系統(tǒng)狀態(tài)機:存儲系統(tǒng)當前狀態(tài)(這是怎么生成的呢?)

snapshot的缺點就是不是增量的昌阿,即使內(nèi)存中某個值沒有變饥脑,下次做snapshot的時候同樣會被dump到磁盤恳邀。當leader需要發(fā)給某個follower的log entry被丟棄了(因為leader做了snapshot)懦冰,leader會將snapshot發(fā)給落后太多的follower∫シ校或者當新加進一臺機器時刷钢,也會發(fā)送snapshot給它。發(fā)送snapshot使用新的RPC乳附,InstalledSnapshot内地。

做snapshot有一些需要注意的性能點,1. 不要做太頻繁赋除,否則消耗磁盤帶寬阱缓。 2. 不要做的太不頻繁,否則一旦節(jié)點重啟需要回放大量日志举农,影響可用性荆针。系統(tǒng)推薦當日志達到某個固定的大小做一次snapshot。3. 做一次snapshot可能耗時過長颁糟,會影響正常log entry的replicate航背。這個可以通過使用copy-on-write的技術(shù)來避免snapshot過程影響正常log entry的replicate。

客戶端命令執(zhí)行過程

  1. 當Leader被選出來后棱貌,即可接受客戶端發(fā)來的請求玖媚,每個請求包含一條需要被狀態(tài)機執(zhí)行的命令。leader會把它作為一個log entry append到日志中婚脱,然后給其它的server發(fā)AppendEntriesRPC請求今魔。

  2. 當Leader確定一個log entry被safely replicated了(大多數(shù)副本已經(jīng)將該命令寫入日志當中),就apply這條log entry到狀態(tài)機中然后返回結(jié)果給客戶端障贸。

  3. 如果某個Follower宕機了或者運行的很慢涡贱,或者網(wǎng)絡(luò)丟包了,則會一直給這個Follower發(fā)AppendEntriesRPC直到日志一致惹想。

當一條日志是commited時问词,Leader才可以將它應(yīng)用到狀態(tài)機中。Raft保證一條commited的log entry已經(jīng)持久化了并且會被所有的節(jié)點執(zhí)行嘀粱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末激挪,一起剝皮案震驚了整個濱河市辰狡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垄分,老刑警劉巖宛篇,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異薄湿,居然都是意外死亡叫倍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門豺瘤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吆倦,“玉大人,你說我怎么就攤上這事坐求〔显螅” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵桥嗤,是天一觀的道長须妻。 經(jīng)常有香客問我,道長泛领,這世上最難降的妖魔是什么荒吏? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮渊鞋,結(jié)果婚禮上绰更,老公的妹妹穿的比我還像新娘。我一直安慰自己篓像,他們只是感情好动知,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著员辩,像睡著了一般盒粮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奠滑,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天丹皱,我揣著相機與錄音,去河邊找鬼宋税。 笑死摊崭,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的杰赛。 我是一名探鬼主播呢簸,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了根时?” 一聲冷哼從身側(cè)響起瘦赫,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蛤迎,沒想到半個月后确虱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡替裆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年校辩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辆童。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡宜咒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胸遇,到底是詐尸還是另有隱情荧呐,我是刑警寧澤汉形,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布纸镊,位于F島的核電站,受9級特大地震影響概疆,放射性物質(zhì)發(fā)生泄漏逗威。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一岔冀、第九天 我趴在偏房一處隱蔽的房頂上張望凯旭。 院中可真熱鬧,春花似錦使套、人聲如沸罐呼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫉柴。三九已至,卻和暖如春奉呛,著一層夾襖步出監(jiān)牢的瞬間计螺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工瞧壮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留登馒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓咆槽,卻偏偏與公主長得像陈轿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

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

  • 最近看了Ongaro在2014年的博士論文《CONSENSUS: BRIDGING THEORY AND PRAC...
    山本聰閱讀 4,594評論 3 11
  • Raft是一種為了管理日志復(fù)制的一致性算法麦射。它提供了和Paxos算法相同的功能和性能赠堵,但是它的算法結(jié)構(gòu)和Paxos...
    WithLin閱讀 807評論 0 1
  • 1 整體描述 在Raft被提出來之前,Paxos協(xié)議是第一個被證明的一致性算法法褥,但是Paxos的論文非常難懂茫叭,導(dǎo)致...
    船_長閱讀 7,226評論 0 7
  • 前言 這是一篇學(xué)習(xí)raft論文的總結(jié),主要是對看論文過程中難以理解的幾個問題的記錄半等。系統(tǒng)性的講解還是得看raft論...
    asmer閱讀 14,466評論 3 38
  • 這篇文章實際上并不是我在閱讀etcd中跟Raft相關(guān)的部分之后得出的揍愁,而是我在讀了ZooKeeper中Zab的實現(xiàn)...
    AlstonWilliams閱讀 1,520評論 0 1