副本機(jī)制與副本同步------《Designing Data-Intensive Applications》讀書筆記6

進(jìn)入到第五章了星瘾,來到了分布式系統(tǒng)之中最核心與復(fù)雜的內(nèi)容:副本與一致性。通常分布式系統(tǒng)會通過網(wǎng)絡(luò)連接的多臺機(jī)器上保存相同數(shù)據(jù)的副本惧辈,所以在本篇之中琳状,我們來展開看看如何去管理和維護(hù)這些副本,以及這個(gè)過程之中會遇到的各種問題盒齿。

1.副本

在數(shù)據(jù)系統(tǒng)之中念逞,我們通常會有這樣幾個(gè)原因來使用副本技術(shù):

  • 保持地理位置接近用戶困食,從而減少延遲(如:Cache,CDN技術(shù)
  • 提高系統(tǒng)的可用性和魯棒性翎承,即使系統(tǒng)中的某些部分已經(jīng)失效了硕盹,仍然可以對外提供服務(wù)。(如:GFS三副本的設(shè)計(jì)
  • 通過擴(kuò)展性來提供讀查詢叨咖,從而增加讀取吞吐量瘩例。(如:ZooKeeper之中的Observer

首先,如果副本的數(shù)據(jù)不隨時(shí)間變化甸各,那么副本的管理是比較簡單的:只需要將數(shù)據(jù)復(fù)制到每個(gè)節(jié)點(diǎn)一次垛贤,就OK了。副本管理真正的困難在于對副本數(shù)據(jù)的修改趣倾,這會涉及到很多瑣碎的問題聘惦。其次,副本復(fù)制時(shí)要考慮許多權(quán)衡儒恋,使用同步還是異步復(fù)制善绎,以及如何處理失效的副本?接下來我們來一一探討這個(gè)問題碧浊。

2.Leader-Follower機(jī)制

如何保障多個(gè)副本在不同節(jié)點(diǎn)上的一致性一直分布式系統(tǒng)之中的一個(gè)核心問題涂邀。分布式系統(tǒng)在寫入數(shù)據(jù)時(shí),需要由每個(gè)副本進(jìn)行處理箱锐;否則比勉,副本將不再包含相同的數(shù)據(jù)。Leader-Follower是一種常見的機(jī)制驹止,我們來梳理一下它的原理:

    1. 一個(gè)節(jié)點(diǎn)上的副本被指定為Leader浩聋。當(dāng)客戶端需要向系統(tǒng)寫入數(shù)據(jù)時(shí),必須將寫入請求發(fā)送給Leader臊恋,由Leader首先將新數(shù)據(jù)寫入本地存儲的副本衣洁。
    1. 管理其他副本的節(jié)點(diǎn)稱為Follower。每當(dāng)Leader將新數(shù)據(jù)寫入本地存儲d的副本時(shí)抖仅,也會將數(shù)據(jù)更改寫入日志之中坊夫。每個(gè)Follower會從Leader那里獲取修改日志,并相應(yīng)地更新數(shù)據(jù)到的本地副本之中撤卢,這樣环凿,所有的在Follower上副本的修改順序會和Leader保持相同的順序。
    1. 當(dāng)客戶端需要從系統(tǒng)之中讀取數(shù)據(jù)時(shí)放吩,它可以查詢Leader或其他Follower智听。(注:Follower與Leader之中的數(shù)據(jù)存在延遲,無法保證強(qiáng)一致性)寫入請求只能由Leader來響應(yīng),或是由Follower轉(zhuǎn)發(fā)給Leader到推。
Leader-Follower機(jī)制

許多關(guān)系數(shù)據(jù)庫在同步副本時(shí)使用這樣的機(jī)制考赛,如PostgreSQL,MySQL莉测,Oracle Data Guard 和SQL Server颜骤。同時(shí)許多非關(guān)系型數(shù)據(jù)庫與分布式消息隊(duì)列也采用這樣的機(jī)制,包括MongoDB悔雹,Rethinkd复哆,Kafka,RabbitMQ腌零。

2.1 同步與異步復(fù)制

在副本進(jìn)行主從復(fù)制時(shí)一個(gè)重要細(xì)節(jié)是復(fù)制是同步還是異步發(fā)生的梯找?(在關(guān)系數(shù)據(jù)庫中,這往往是一個(gè)可配置的選項(xiàng)益涧。在其他系統(tǒng)之中锈锤,如Ceph,是系統(tǒng)默認(rèn)的)

同步復(fù)制與異步復(fù)制的響應(yīng)時(shí)間的比較

由上圖可知闲询,同步復(fù)制有相當(dāng)大的延遲久免,而異步復(fù)制的響應(yīng)相當(dāng)快速。但是異步復(fù)制卻不能保證完成所需要多長時(shí)間扭弧。有些情況下阎姥,F(xiàn)ollower的數(shù)據(jù)可能比Leader上的數(shù)據(jù)落后幾分鐘或更多。如:節(jié)點(diǎn)之間存在網(wǎng)絡(luò)問題或節(jié)點(diǎn)的故障恢復(fù)鸽捻。如果Leader失敗且不可恢復(fù)呼巴,則尚未復(fù)制到Follower的任何寫操作都將丟失。

而同步復(fù)制的優(yōu)點(diǎn)是保證了Follower與Leader之間的副本一致性御蒲,一旦任意一個(gè)Leader失效了衣赶,任何一個(gè)Follower的數(shù)據(jù)都與Leader相同。但是同步復(fù)制一旦出現(xiàn)網(wǎng)絡(luò)或節(jié)點(diǎn)的故障厚满,會導(dǎo)致無法處理寫入府瞄。Leader必須阻止所有寫入并等待Follow上的副本再次可用。如果所有的Follower都是同步復(fù)制碘箍,那么任何一個(gè)節(jié)點(diǎn)的中斷都會導(dǎo)致整個(gè)系統(tǒng)癱瘓遵馆。在實(shí)際運(yùn)用之中,如果在數(shù)據(jù)庫上啟用同步復(fù)制丰榴,通常其中一個(gè)副本是同步復(fù)制的团搞,而另一個(gè)是異步復(fù)制的。如果同步的副本變得不可用或十分緩慢多艇,可以將同步操作切換到另一個(gè)異步副本之中。這樣保證了至少兩個(gè)節(jié)點(diǎn)上有一個(gè)數(shù)據(jù)的最新副本:Leader和一個(gè)同步Follower像吻。這種配置稱之為半同步峻黍。(鏈?zhǔn)綇?fù)制也是類似于半同步的一種復(fù)制機(jī)制复隆,不丟失數(shù)據(jù)但仍能提供良好性能和可用性的復(fù)制方法。)

2.2 添加新的Follower

有時(shí)我們需要添加新的Follower來增加副本的數(shù)量姆涩,或者替換失敗的節(jié)點(diǎn)挽拂。此時(shí)就需要確保新的Follower擁有一個(gè)正確的副本的數(shù)據(jù)。僅僅將數(shù)據(jù)文件從一個(gè)節(jié)點(diǎn)復(fù)制到另一個(gè)節(jié)點(diǎn)通常是不夠的:客戶端不停向系統(tǒng)寫入數(shù)據(jù)骨饿,所以數(shù)據(jù)副本總是處于不斷變化的狀態(tài)亏栈。這里可以簡單地通過鎖定系統(tǒng),使其拒絕客戶端的寫請求來使各個(gè)副本上保持一致宏赘,但這樣會大大降低系統(tǒng)的可用性绒北。所以我們需要一個(gè)不停機(jī)的方式來添加新的Follower:

  • 1.在某個(gè)時(shí)間點(diǎn)對Leader的副本進(jìn)行快照,并且將快照復(fù)制到新加入的Follower節(jié)點(diǎn)察署。

  • 2 .Follower連接到Leader闷游,并向Leader請求快照之后所有的數(shù)據(jù)更改。通常是Leader節(jié)點(diǎn)的日志序列號贴汪。

    1. 當(dāng)Follower處理完快照之后的數(shù)據(jù)更改之后脐往,它就可以正常處理來自Leader的數(shù)據(jù)更改了。
2.3 節(jié)點(diǎn)故障

在分布式系統(tǒng)之中扳埂,任何節(jié)點(diǎn)都可能出現(xiàn)故障业簿,而能夠在不停機(jī)的情況下重新啟動(dòng)單個(gè)節(jié)點(diǎn)是操作和維護(hù)是十分必要的。盡管每個(gè)節(jié)點(diǎn)故障阳懂,但我們需要讓一個(gè)節(jié)點(diǎn)停機(jī)的影響盡可能小梅尤。

  • Follower故障

在Follower的本地磁盤上,都保存著從Leader收到的數(shù)據(jù)更改的日志希太。當(dāng)一個(gè)Follower崩潰并重新啟動(dòng)克饶,或者Leader與Follower之間的網(wǎng)絡(luò)暫時(shí)中斷。Follower可從它的日志找到故障發(fā)生之前處理的最后一個(gè)事務(wù)誊辉,然后連接到Leader并請求在Follower斷開連接的時(shí)候發(fā)生的所有數(shù)據(jù)變化矾湃。(這個(gè)流程和添加新的Follower其實(shí)是同樣的思路

  • Leader故障

在處理Leader的失敗時(shí)顯然會更為棘手:其中一個(gè)Follower需要被提升為新的Leader,客戶端也需要識別并且將后續(xù)的請求發(fā)送給新的Leader堕澄,而其他的Follower則需要開始在新Leader之下工作邀跃。處理Leader故障通常是如下的流程:

  • 1、確認(rèn)Leader失效蛙紫。絕大多數(shù)系統(tǒng)使用超時(shí)機(jī)制:如果一個(gè)節(jié)點(diǎn)不響應(yīng)一段時(shí)間拍屑,例如,30秒坑傅,它被認(rèn)為是失效了僵驰。(如果是中心化的系統(tǒng)可以采用Lease機(jī)制。筆者在碩士生階段對Cassandra數(shù)據(jù)庫有過系統(tǒng)的調(diào)研,在Cassandra中采用了由日本學(xué)者Naohiro Hayashibara提出的《The Phi Accrual Failure Detector》失敗探測算法蒜茴,通過多維度累積量來判斷節(jié)點(diǎn)是否失效星爪,不失為一個(gè)好的解決方案,十分適合類P2P架構(gòu)的分布式系統(tǒng)

  • 2粉私、選取新的Leader顽腾。在中心化架構(gòu)之中,如HDFS诺核,新的Leader可以用中心化節(jié)點(diǎn)指定抄肖。而在非中心化的架構(gòu)之中,則可以通過選舉過程來完成窖杀,分布式系統(tǒng)之中的選舉協(xié)議有很多:2PC漓摩,3PC,Paxos陈瘦,Raft等等幌甘。

  • 3、調(diào)整系統(tǒng)配置以使用新的Leader痊项。如果舊的Leader回歸到集群锅风,它可能仍然認(rèn)為自己是Leader,這時(shí)需要確保舊的Leader成為Follower并承認(rèn)新的Leader鞍泉。

如果是異步復(fù)制的場景皱埠,新的Leader可能舊的Leader之前的完整的寫入信息。最常見的解決方案是丟棄舊Leader之前寫入多于新Leader的信息丟棄咖驮,但是這顯然違反了數(shù)據(jù)系統(tǒng)寫入持久性的要求边器。
在某些故障場景中,可能會出現(xiàn)兩個(gè)節(jié)點(diǎn)都認(rèn)為他們是Leader托修,這種情況被稱為腦裂忘巧。此時(shí)兩個(gè)Leader都會接受寫請求搅裙,數(shù)據(jù)很可能會出現(xiàn)丟失或損壞凰盔。
什么時(shí)候進(jìn)行故障切換也是一個(gè)值得探討的問題:較長的超時(shí)時(shí)間意味著在Leader失效的情況下恢復(fù)時(shí)間更長。然而照瘾,如果時(shí)間太短涩拙,可能會有不必要的故障轉(zhuǎn)移际长。例如,臨時(shí)負(fù)載高峰時(shí)刻可能導(dǎo)致節(jié)點(diǎn)的響應(yīng)時(shí)間增加到超時(shí)兴泥,那么不必要的故障轉(zhuǎn)移會使情況變得更糟工育,而不是更好。為此搓彻,一些運(yùn)營團(tuán)隊(duì)更愿意執(zhí)行手動(dòng)的故障轉(zhuǎn)移如绸,即使系統(tǒng)本身支持自動(dòng)的故障轉(zhuǎn)移嘱朽。

3. 日志的復(fù)制

日志在副本的一致性之中是至關(guān)重要的,所以我們接下來簡要的梳理一下日志復(fù)制可用的方法:

  • Statement-Based復(fù)制
    在最簡單的情況下怔接,Leader將每個(gè)寫請求通過日志的形式發(fā)送給Follower燥翅。每個(gè)Follower解析和執(zhí)行對應(yīng)的操作語句,雖然這聽起來很合理蜕提,但是實(shí)際操作中會存在一些坑:
    (1) 非確定性函數(shù),如now()獲得當(dāng)前的日期和時(shí)間或rand()得到一個(gè)隨機(jī)數(shù)靶端,這樣會導(dǎo)致副本之間的不一致谎势。(這里可以轉(zhuǎn)換思維,用一個(gè)確定的修改值杨名,來替換不確定性的函數(shù)調(diào)用)
    (2) 如果使用一個(gè)自動(dòng)遞增的列脏榆,或如果他們依賴于數(shù)據(jù)庫中的現(xiàn)有數(shù)據(jù)(例如,更新…在<條件>)台谍,他們必須執(zhí)行完全相同的順序在每個(gè)副本须喂,否則也會產(chǎn)生不一致性。(異步轉(zhuǎn)發(fā)趁蕊,亂序到達(dá)坞生。這個(gè)可以通過操作序列號等強(qiáng)制要求進(jìn)行規(guī)避。
    (3) 有副作用的語句(例如觸發(fā)器掷伙、存儲過程是己、用戶定義函數(shù))可能會導(dǎo)致每個(gè)副本上出現(xiàn)不同的副作用。

  • Write-ahead日志復(fù)制
    日志是一個(gè)只包含所有寫入操作的字節(jié)序列任柜。我們可以使用完全相同的日志來在另一個(gè)節(jié)點(diǎn)上構(gòu)建一個(gè)副本卒废。Leader將日志寫入磁盤之后,將它通過網(wǎng)絡(luò)發(fā)送給Follower宙地。當(dāng)Follower處理這個(gè)日志時(shí)摔认,它構(gòu)建了一個(gè)與Leader完全相同的數(shù)據(jù)結(jié)構(gòu)的副本。這種方式的缺點(diǎn)是:日志在非常低的級別上描述數(shù)據(jù)宅粥。這使得數(shù)據(jù)拷貝與存儲引擎緊密耦合参袱。

  • Row-based日志復(fù)制
    Row-based與Write-ahead的方法類似,但是它允許復(fù)制日志與存儲引擎內(nèi)部分離粹胯。這種日志稱為邏輯日志蓖柔,邏輯日志通常是描述在一個(gè)行的粒度上記錄寫入操作:
    對于插入的行,日志包含所有列的新值风纠。
    對于已刪除的行况鸣,日志包含足夠的信息以唯一地標(biāo)識刪除的行。(主鍵
    對于更新的行竹观,日志包含足夠的信息以唯一地標(biāo)識更新的行镐捧,以及所有列的新值潜索。
    由于邏輯日志與存儲引擎內(nèi)部分離,因此可以更容易地保持向后兼容懂酱,從而允許Leader與Follower運(yùn)行不同版本的數(shù)據(jù)系統(tǒng)竹习,甚至是不同的存儲引擎。同時(shí)列牺,邏輯日志格式對外部應(yīng)用程序也更容易解析整陌。可以將邏輯日志的內(nèi)容發(fā)送到外部系統(tǒng)(如用于離線分析的數(shù)據(jù)倉庫)瞎领,或者用于構(gòu)建自定義索引和緩存泌辫。

4. 復(fù)制延遲

副本可以增加系統(tǒng)的可伸縮性(處理比單個(gè)機(jī)器處理更多的請求)和降低延遲(將副本放置在離用戶更近的地方)。寫入操作必須通過Leader副本九默,但是只讀查詢可以在任何副本上進(jìn)行震放。 對于一次寫入,多次讀取的應(yīng)用來說驼修,采用讀擴(kuò)展架構(gòu)是十分合理的殿遂。但是由于上文提及的原因,我們通常不會采用同步復(fù)制的方式乙各。這將導(dǎo)致數(shù)據(jù)出現(xiàn)明顯的不一致性:如果您同時(shí)對Leader和Follwer執(zhí)行相同的查詢墨礁,可能會得到不同的結(jié)果,因?yàn)椴⒉皇撬械膶懭雽?shí)時(shí)在Follower上反饋觅丰。這種不一致性僅僅是暫時(shí)狀態(tài)饵溅,所以這種情況被稱為最終一致性。

對于這種情況我們應(yīng)該這么去處理和理解妇萄,我們下回分解~~~(第五章的內(nèi)容炒雞多蜕企,接下來會通過多篇讀書筆記來給大家梳理,講解冠句,下一篇再見~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轻掩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子懦底,更是在濱河造成了極大的恐慌唇牧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聚唐,死亡現(xiàn)場離奇詭異丐重,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杆查,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門扮惦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人亲桦,你說我怎么就攤上這事崖蜜∽瞧停” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵豫领,是天一觀的道長抡柿。 經(jīng)常有香客問我,道長等恐,這世上最難降的妖魔是什么洲劣? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮课蔬,結(jié)果婚禮上闪檬,老公的妹妹穿的比我還像新娘。我一直安慰自己购笆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布虚循。 她就那樣靜靜地躺著同欠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪横缔。 梳的紋絲不亂的頭發(fā)上铺遂,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音茎刚,去河邊找鬼襟锐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛膛锭,可吹牛的內(nèi)容都是我干的粮坞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼初狰,長吁一口氣:“原來是場噩夢啊……” “哼莫杈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起奢入,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤筝闹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后腥光,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體关顷,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年武福,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了议双。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡艘儒,死狀恐怖聋伦,靈堂內(nèi)的尸體忽然破棺而出夫偶,到底是詐尸還是另有隱情,我是刑警寧澤觉增,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布兵拢,位于F島的核電站,受9級特大地震影響逾礁,放射性物質(zhì)發(fā)生泄漏说铃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一嘹履、第九天 我趴在偏房一處隱蔽的房頂上張望腻扇。 院中可真熱鬧,春花似錦砾嫉、人聲如沸幼苛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舶沿。三九已至,卻和暖如春配并,著一層夾襖步出監(jiān)牢的瞬間括荡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工溉旋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畸冲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓观腊,卻偏偏與公主長得像邑闲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子梧油,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

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