Raft算法在Curve中的實(shí)踐

姓名:鄧復(fù)元

學(xué)號(hào)17020120041

轉(zhuǎn)載自:https://blog.csdn.net/NetEaseResearch/article/details/110006508

【嵌牛導(dǎo)讀】:本文介紹了RAFT算法的特點(diǎn)和基本應(yīng)用

【嵌牛鼻子】:Curve實(shí)踐

【嵌牛模塊】:RAFT算法概念彤钟、特點(diǎn)、應(yīng)用場合

【嵌牛正文】:

urve作為高性能、高可用苛秕、高可靠的新一代分布式存儲(chǔ)系統(tǒng),對(duì)于多副本數(shù)據(jù)同步榔组,負(fù)載均衡搞坝,容災(zāi)恢復(fù)方面都有較高的要求。Curve選用Raft算法作為底層一致性協(xié)議喉祭,并基于Raft的特性养渴,實(shí)現(xiàn)了異常情況下的數(shù)據(jù)遷移和自動(dòng)恢復(fù)。下面首先簡要介紹一下Raft算法的一些基本概念和術(shù)語泛烙,再詳細(xì)介紹其在Curve中的實(shí)踐理卑。

Raft一致性算法介紹

Raft算法中,有Leader蔽氨,F(xiàn)ollower藐唠,Candidate三種角色,它們之間的轉(zhuǎn)換關(guān)系如下圖:


在同一時(shí)刻鹉究,只能有一個(gè)Leader宇立,當(dāng)選Leader后到發(fā)起下一次選舉稱為一個(gè)任期(term),Leader負(fù)責(zé)通過心跳向follower保持統(tǒng)治自赔,并同步數(shù)據(jù)給Follower妈嘹。Follower發(fā)起選舉的前提是超時(shí)未收到Leader的心跳。

Leader競選:RAFT是一種Majority的協(xié)議绍妨,即贏得選舉的條件是獲得包括自己以內(nèi)的大多數(shù)節(jié)點(diǎn)的投票润脸。Follower超時(shí)未收到Leader的心跳,則會(huì)成為Candidate痘绎,發(fā)起新一輪的選舉津函。每個(gè)節(jié)點(diǎn)在每個(gè)Term內(nèi)只能投一次票,且服從先到先服務(wù)原則孤页。為了避免多個(gè)Follower同時(shí)超時(shí)尔苦,raft中的選舉超時(shí)時(shí)間是一個(gè)固定時(shí)間加一個(gè)隨機(jī)時(shí)間。

日志復(fù)制:在任期內(nèi)行施,Leader接收來自client的請(qǐng)求允坚,并將其封裝成一個(gè)日志條目(Raft Log Entry)把它append到自己的raft log中,然后并行地向其它服務(wù)器發(fā)起AppendEntries RPC蛾号,當(dāng)確定該entry被大多數(shù)節(jié)點(diǎn)成功復(fù)制后(這個(gè)過程叫commit)稠项,就可以執(zhí)行命令(這一步叫apply),并返回給client結(jié)果鲜结。log entry由三個(gè)部分組成展运,分別是:1、log index精刷,2拗胜、log所屬的term,3怒允、要執(zhí)行的命令埂软。

配置變更:在Raft中,稱復(fù)制組有哪些成員稱為配置纫事,配置并不是固定的勘畔,會(huì)根據(jù)需求增刪節(jié)點(diǎn)或異常情況下需要替換掉有問題的節(jié)點(diǎn)所灸。從一個(gè)配置直接切換到另一個(gè)配置是不安全的,因?yàn)椴煌姆?wù)器會(huì)在不同的時(shí)間點(diǎn)進(jìn)行切換炫七。因此Raft配置變更時(shí)爬立,會(huì)先創(chuàng)建一個(gè)特殊的log entry Cold,new,這條entry被commit后诉字,會(huì)進(jìn)入共同一致階段懦尝,即新舊配置一起做決定知纷。這時(shí)候壤圃,再生成一個(gè)Cnew的log entry,等這條entry被commit后琅轧,就可以由新配置獨(dú)立做決定了伍绳。

安裝快照:Raft快照指的是某個(gè)時(shí)刻保存下來的系統(tǒng)狀態(tài)的集合≌Ч穑快照有兩方面的作用:一個(gè)是日志壓縮冲杀,打了快照之后,在此時(shí)刻之前的log entry就可以刪除了睹酌。另一個(gè)是啟動(dòng)加速权谁,系統(tǒng)起來的時(shí)候不需要重新回放所有日志。當(dāng)Leader同步日志給Follower的時(shí)候憋沿,發(fā)現(xiàn)所需的log entry已經(jīng)被快照刪掉了旺芽,即可通過發(fā)送InstallSnapshot RPC給Follower進(jìn)行同步。

Raft算法在Curve中的應(yīng)用

Curve系統(tǒng)是一個(gè)分布式存儲(chǔ)系統(tǒng)辐啄,在Curve系統(tǒng)中采章,數(shù)據(jù)分片的最小單位稱之為Chunk,默認(rèn)的Chunk大小是16MB壶辜。在大規(guī)模的存儲(chǔ)容量下悯舟,會(huì)產(chǎn)生大量的Chunk,如此眾多的Chunk砸民,會(huì)對(duì)元數(shù)據(jù)的存儲(chǔ)抵怎、管理產(chǎn)生一定壓力。因此引入CopySet的概念岭参。CopySet可以理解為一組ChunkServer的集合反惕,一個(gè)Copyset管理多個(gè)Chunk,多副本間的同步和管理已Copyset為單位組織冗荸。ChunkServer承璃,Copyset和Chunk三者之間的關(guān)系如下圖:

Curve copyset選用了braft作為一致性協(xié)議的組件,使用方式為multi-raft蚌本,即同一個(gè)機(jī)器盔粹,可以屬于多個(gè)復(fù)制組隘梨,反過來說,一個(gè)機(jī)器上舷嗡,可以存在多個(gè)raft實(shí)例轴猎。基于braft进萄,我們實(shí)現(xiàn)了副本間數(shù)據(jù)同步捻脖,系統(tǒng)調(diào)度,輕量級(jí)raft快照等功能中鼠,下面一一詳細(xì)介紹可婶。

副本間數(shù)據(jù)同步

CopysetNode在ChunkServer端封裝了braft node,具體關(guān)系如下圖所示:

Curve client發(fā)送一個(gè)寫請(qǐng)求時(shí)援雇,三副本情況下的具體的步驟如下:

Client發(fā)送寫請(qǐng)求給Leader ChunkServer

ChunkServer收到請(qǐng)求矛渴,將請(qǐng)求封裝成一個(gè)log entry,提交給raft

braft模塊在本地持久化entry的同時(shí)發(fā)送entry給其他副本(ChunkServer)

本地持久化entry成功惫搏,且另一個(gè)副本也落盤成功則commit

commit后執(zhí)行apply具温,apply即執(zhí)行我們的寫盤操作。

在此過程中筐赔,用戶的數(shù)據(jù)和操作铣猩,通過braft中的log entry的方式在副本間傳遞,進(jìn)行數(shù)據(jù)同步茴丰。在三副本場景下达皿,向上層返回的時(shí)間取決于兩個(gè)較快的副本的速度,因此可以減少慢盤的影響较沪。對(duì)于較慢的那個(gè)副本鳞绕,leader也會(huì)通過無限重試的方式同步數(shù)據(jù),因此在系統(tǒng)正常工作的前提下尸曼,最終三個(gè)副本的數(shù)據(jù)是一致的们何。

基于Raft的系統(tǒng)調(diào)度

在Curve中,ChunkServer定期向元數(shù)據(jù)節(jié)點(diǎn)MDS上報(bào)心跳控轿,心跳中除了ChunkServer自身的一些統(tǒng)計(jì)信息冤竹,還包含ChunkServer上面的CopySet的統(tǒng)計(jì)信息,包含它的leader茬射,復(fù)制組成員鹦蠕,是否有配置變更執(zhí)行中,配置的epoch等在抛。MDS基于這些統(tǒng)計(jì)信息钟病,會(huì)生成一系列的Raft配置變更請(qǐng)求并下發(fā)給Copyset的leader所在的ChunkServer。

下發(fā)配置變更

Curve ChunkServer會(huì)定期向MDS上報(bào)心跳。MDS調(diào)度下發(fā)配置變更是在心跳的response中完成的肠阱。上報(bào)心跳的過程如下圖:

心跳是定時(shí)任務(wù)觸發(fā)的票唆,ChunkServer除了上報(bào)一些自己的容量信息等統(tǒng)計(jì)信息外,還會(huì)上報(bào)Copyset的一些信息屹徘,比如leader走趋,成員,epoch噪伊,是否有進(jìn)行中的配置變更等簿煌。

MDS在心跳response中下發(fā)配置變更的過程如下圖:

ChunkServer收到response后,解析其中的配置變更信息鉴吹,并下發(fā)給每個(gè)Copyset姨伟。

Curve epoch

epoch同步配置。MDS生成的調(diào)度信息拙寡,是由后臺(tái)定時(shí)任務(wù)觸發(fā)授滓,并在ChunkServer下一次請(qǐng)求到來時(shí)在response中下發(fā)的琳水,因此MDS下發(fā)的配置變更有可能是過期的肆糕。為了實(shí)現(xiàn)MDS和ChunkServer之間的配置同步,Curve引入了epoch機(jī)制在孝,初始狀態(tài)诚啃,epoch初始為0,每進(jìn)行一次配置變更(包括leader變更)私沮,epoch都會(huì)加一始赎。當(dāng)MDS中的epoch等于ChunkServer端的epoch時(shí),即將下發(fā)的配置變更才認(rèn)為是有效的仔燕。epoch與term有何區(qū)別造垛?term用于表示Leader的任期,即只跟選舉有關(guān)晰搀,而epoch是與配置變更相關(guān)的五辽,也包括了Leader選舉這種情況。

epoch的更新外恕。epoch是在ChunkServer端更新的杆逗,braft在實(shí)現(xiàn)上提供了一個(gè)用戶狀態(tài)機(jī),在braft內(nèi)部發(fā)生變化鳞疲,比如apply罪郊,出錯(cuò),關(guān)閉尚洽,打快照悔橄,加載快照,leader變更,配置變更等時(shí)會(huì)調(diào)用用戶狀態(tài)機(jī)中對(duì)應(yīng)的函數(shù)癣疟。Curve copyset通過繼承的方式實(shí)現(xiàn)這個(gè)用戶狀態(tài)機(jī)來完成與braft的交互尺铣,epoch是在on_configuration_committed函數(shù)中加一的。在braft中争舞,當(dāng)Leader變更的時(shí)候會(huì)把當(dāng)前的配置再提交一遍凛忿,因此在on_configuration_committed中增加epoch即可保證在配置發(fā)生變化或者Leader變更時(shí)epoch順序遞增。

epoch的持久化竞川。在MDS端店溢,epoch隨著CopySet的其他信息一起持久化在etcd中。ChunkServer也對(duì)epoch進(jìn)行了持久化委乌,但是ChunkServer中持久化epoch并不是每次epoch發(fā)生變化都需要持久化的床牧。這是利用了raft的日志回放和快照功能≡饷常考慮以下兩種情況:

假設(shè)raft沒有打快照戈咳,那么就不需要持久化epoch,因?yàn)樗胁僮魅罩竞敬担ㄅ渲米兏膃ntry都已持久化著蛙,當(dāng)服務(wù)重啟的時(shí)候,回放這些日志的時(shí)候會(huì)依次再調(diào)用一遍on_configuration_committed耳贬,最后epoch會(huì)恢復(fù)到重啟前的值踏堡。

當(dāng)raft有快照時(shí),打快照前的entry都會(huì)被刪除咒劲,就不能通過上面的方式回放顷蟆,因此必須要持久化。但我們只需要在打raft快照時(shí)持久化epoch的當(dāng)前值即可腐魂。這樣當(dāng)系統(tǒng)重啟的時(shí)候帐偎,會(huì)先安裝raft快照,安裝后epoch恢復(fù)到快照時(shí)的值蛔屹,再通過執(zhí)行后面的log entry削樊,最終epoch恢復(fù)到重啟前的值。在打快照時(shí)更新epoch是在on_snapshot_save函數(shù)中完成的判导。

Raft輕量級(jí)快照

上面介紹Raft算法的時(shí)候介紹過嫉父,Raft需要定時(shí)打快照,以清理老的log entry眼刃,否則Raft日志會(huì)無限增長下去绕辖。打快照的時(shí)候需要保存系統(tǒng)當(dāng)前的狀態(tài),對(duì)于Curve塊存儲(chǔ)場景來說擂红,系統(tǒng)狀態(tài)就是Chunk當(dāng)前的數(shù)據(jù)仪际。直觀的方案是將打快照時(shí)刻的全部chunk拷貝一遍備份起來围小。但是這樣有兩個(gè)問題:

空間上要多出一倍,空間浪費(fèi)非常嚴(yán)重

Curve默認(rèn)打快照的間隔是30分鐘一次树碱,這種方案下會(huì)有頻繁的數(shù)據(jù)拷貝肯适,對(duì)磁盤造成很大的壓力,影響正常的IO成榜。

因此框舔,Curve中使用的Raft快照是輕量級(jí)的,即打快照的時(shí)候只保存當(dāng)前的Chunk文件的列表赎婚,不對(duì)Chunk本身做備份刘绣。具體流程如下:

這樣會(huì)導(dǎo)致Follower下載到的chunk文件不是打快照時(shí)的狀態(tài),而是最新的狀態(tài)挣输,在回放日志的時(shí)候纬凤,會(huì)把這些新數(shù)據(jù)再寫一遍。但這對(duì)于我們的場景是可以接受的撩嚼,因?yàn)榈讓佣际歉采w寫是冪等的停士,即寫一次和寫多次結(jié)果是一致的。

小結(jié)

本篇文章首先介紹了Raft一致性算法的一些基本概念完丽。隨后介紹了Raft算法新一代高性能分布式存儲(chǔ)系統(tǒng)Curve中的應(yīng)用恋技,分別從數(shù)據(jù)同步,系統(tǒng)調(diào)度和Raft快照三個(gè)角度介紹了Curve中使用Raft的細(xì)節(jié)舰涌。關(guān)于Curve的更進(jìn)一步介紹詳見我們的代碼倉庫:https://github.com/opencurve/curve猖任。另外,Curve開源分享也在火熱進(jìn)行中瓷耙,分享的ppt可以在https://github.com/opencurve/curve-meetup-slides倉庫中獲取。

作者:查日蘇刁赖,網(wǎng)易數(shù)帆存儲(chǔ)團(tuán)隊(duì)高級(jí)C++開發(fā)工程師搁痛,高性能分布式存儲(chǔ)系統(tǒng)Curve核心開發(fā)。

如有理解和描述上有疏漏或者錯(cuò)誤的地方宇弛,歡迎共同交流鸡典;參考已經(jīng)在參考文獻(xiàn)中注明,但仍有可能有疏漏的地方枪芒,有任何侵權(quán)或者不明確的地方彻况,歡迎指出,必定及時(shí)更正或者刪除舅踪;文章供于學(xué)習(xí)交流纽甘,轉(zhuǎn)載注明出處

[1] Ongaro D, Ousterhout J. In search of an understandable consensus algorithm[C]//2014 {USENIX} Annual Technical Conference ({USENIX}{ATC} 14). 2014: 305-319.

相關(guān)視頻:

Curve核心組件之ChunkServer數(shù)據(jù)節(jié)點(diǎn)


相關(guān)文章:

Curve技術(shù)解析之MDS元數(shù)據(jù)管理

分布式存儲(chǔ)開發(fā):Curve中的內(nèi)存管理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市抽碌,隨后出現(xiàn)的幾起案子悍赢,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件左权,死亡現(xiàn)場離奇詭異皮胡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)赏迟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門屡贺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锌杀,你說我怎么就攤上這事烹笔。” “怎么了抛丽?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵谤职,是天一觀的道長。 經(jīng)常有香客問我亿鲜,道長允蜈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任蒿柳,我火速辦了婚禮饶套,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垒探。我一直安慰自己妓蛮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布圾叼。 她就那樣靜靜地躺著蛤克,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夷蚊。 梳的紋絲不亂的頭發(fā)上构挤,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音惕鼓,去河邊找鬼筋现。 笑死,一個(gè)胖子當(dāng)著我的面吹牛箱歧,可吹牛的內(nèi)容都是我干的矾飞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼呀邢,長吁一口氣:“原來是場噩夢啊……” “哼洒沦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起驼鹅,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤微谓,失蹤者是張志新(化名)和其女友劉穎森篷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豺型,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仲智,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姻氨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钓辆。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肴焊,靈堂內(nèi)的尸體忽然破棺而出前联,到底是詐尸還是另有隱情,我是刑警寧澤娶眷,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布似嗤,位于F島的核電站,受9級(jí)特大地震影響届宠,放射性物質(zhì)發(fā)生泄漏烁落。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一豌注、第九天 我趴在偏房一處隱蔽的房頂上張望伤塌。 院中可真熱鬧,春花似錦轧铁、人聲如沸每聪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽药薯。三九已至,卻和暖如春聂宾,著一層夾襖步出監(jiān)牢的瞬間果善,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工系谐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人讨跟。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓纪他,卻偏偏與公主長得像,于是被迫代替她去往敵國和親晾匠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茶袒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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