過去這幾十年,分佈式系統的「數據一致性」精華都在這了!

此次準備開啓一個新的系列來寫了,聊聊分佈式系統中的關注點。節奏不會排的太緊湊,計劃兩週一更吧。

本文是本系列的第三篇。與前兩篇《不知道是否是最通俗易懂的《數據一致性》剖析了》、《煩人的數據不一致到底怎麼解決?——經過「共識」達成數據一致性》造成完整的「數據一致性」合集。web

1、爲何須要事務

若是說「共識」解決的是「水平」問題,那麼「事務」解決的是「垂直」問題。是如何讓一條繩上的螞蚱共同起舞?數據庫

事務只是一個計算機術語,而事務的體現形式其實在咱們生活中也無處不在。任何咱們認爲應該是這樣的事情,去確保它達到預期的過程就是「事務」。 往小了說,咱們平時在走路的時候,向前擺動左手的同時擡右腿,若是不是這樣的話就是不一致,別人會說你走路不協調。因此咱們小時候父母會經過各類方式教會咱們這個,這些各式各樣的方式就比如咱們在軟件開發中去實施「事務」同樣,一題是多解的。緩存

2、事務的來源

提到事務不得不提到「XA規範」[1],這是分佈式還沒大行其道的時期,被大多數的數據庫做爲其內部分佈式事務實現的接口標準。微信

圖片來源於論文中,版權歸原做者全部

「XA規範」就是上圖中「RM」和「TM」的交互規範和接口定義。僅僅是定義了xa_和ax_系列的函數原型以及功能描述、約束和實施規範等,並不包括建議的實現方式。後面會提到的兩階段提交(2PC)是「TM」協調「RM」們完成事務的方法。網絡

因此其實能夠說,事務起源於數據庫,輝煌於分佈式系統。在摩爾定律還適用的時候,軟件系統爲了承載更大的流量或者說用戶數,開始運用「分治」的思想來設計。而後隨着互聯網的蓬勃發展,B/S應用大行其道的背景下,分佈式系統愈來愈常見。而且隨着一個個巨無霸互聯網公司的出現,愈來愈被鼓吹和傳頌。架構

一輪明月的背後是一個陰暗面,歷來不讓人看見。

能被吹捧的永遠是有益的一面,再加上耀眼的數據:多少TPS、多少QPS,更抓人眼球。可是這背後爲了讓「分治」後的系統可以儘量的像單個個體同樣運做,各種專家學者們經過多年研究,纔有了現在的各類著名理論和解決方案。框架

3、分佈式系統中的事務問題

正如前面所說,事務問題其實一直存在,只是在分佈式系統中被放大了。而且隨着系統拆分的粒度越細,問題的複雜度成指數上升。異步

分佈式系統的事務,不得不提到被廣爲流傳的兩個理論:「CAP」、「BASE」。分佈式

「CAP」理論由Eric Brewer在2000年PODC會議上提出[2],因此還被稱爲Brewer定理。是Eric Brewer在Inktomi期間研發搜索引擎、分佈式web緩存時得出的一個猜測:ide

It is impossible for a web service to provide the three following guarantees : Consistency, Availability and Partition-tolerance.

後來Seth Gilbert和Nancy Lynch對其進行了證實[3],成爲咱們熟知的「CAP」定理(感謝園友@bangerlee的信息收集)。

對,就是下面這張經典的圖。
圖片來源於網絡,版權歸原做者全部

  • 一致性(consistency):這裏的一致性指是「線性一致性」。(關於線性一致性的解釋,點我可閱讀)
  • 可用性(availability):每一個請求都在必定時限內獲得響應。
  • 分區容忍性(partition-tolerance):這應該是這三點中最晦澀的。容許丟失以一個節點發給另外一個節點的任意多的消息。只要是分佈式系統,這項是沒法逃避的,由於網絡、硬件說不許啥時候就出問題了。

舉個不是特別嚴謹的例子,這就比如要實現一個系統不能產生BUG(C),而且10天內完成上線(A),以及須要多人團隊一塊兒協做進行(P)。咱們作開發的也很清楚這三者是沒法兼得的。何況只要是一個組織,團隊協做是沒法避免的,正如這裏的分區容忍性同樣,好比得考慮人員請假的問題。剩下的2項,若是說能夠達到沒有BUG的話,那就是時間無限延長,但也只是無限趨近於0,並不能達到真正的0,由於沒有人能夠保證發現了全部的BUG。

「BASE」理論是由時任ebay架構師的Dan Pritchett提出的[4],本質上就是對「線性一致性」的弱化。弱化的方式正如本集合的第一篇文章中所提到的「順序一致性」和「最終一致性」。(關於這兩種一致性的解釋,點我可閱讀)

「BASE」理論解釋以下:

  • 基本可用(Basically Available)。分佈式系統在出現故障時,容許損失部分可用功能,保證核心功能可用。
  • 軟狀態(Soft State)。狀態能夠有一段時間不一樣步,且這個狀態不影響系統可用性。
  • 最終一致(Eventually Consistent)。確保最終數據可以一致,而不是時時保持強一致。

「BASE」理論的提出並非取代「CAP」理論,讓咱們在實際的工做中就能夠徹底的撇開「線性一致性」。並非這樣,而是引導咱們能夠區分核心和非核心,而後分別對待,核心部分仍是須要用CAP理論來保證「線性一致性」。爲何要區別對待?根本上仍是沒法容忍「線性一致性」帶來的巨大的性能損耗,由於它是反可伸縮性的。可是隻要涉及到Money之類的高敏感數據的操做部分,仍是必須保證「線性一致性」。

仍是上面的例子,咱們側重於下降核心功能的BUG,不花過多精力在非核心功能上(BA)。咱們容許產生不影響核心功能的BUG(S),可是必須最終要修復(E)。

4、分佈式事務的解決方案

若是說「CAP」理論和「BASE」理論是「道」,那麼圍繞這兩個理論演化的解決方案就是「術」。對咱們來講,在實際的運用中根據所處的場景找到最合適的,是咱們最重要的事。

以「CAP」爲基礎的強一致性解決方案都會引入一個相似「協調器」的東西來做爲全局事務的掌控者,能夠來看一下。

01 兩階段提交(2PC)[5]

圖片來源於網絡,版權歸原做者全部

印象中左耳朵耗子(陳皓)以前拿西方結婚時的儀式作過一個形象的比喻。大體好像是牧師分別詢問男女雙方「你願意嗎?」至關於這裏的「請求提交」,獲得的「yes」至關於「是」這個答覆。而後再要求給對方帶上戒指,這個要求就至關於這裏的「提交」,帶完戒指以後的反饋就是「ACK」。

另外值得注意的是,參與者在答覆「是」以前會將本身的內部資源變爲阻塞狀態。所以若是在產生阻塞後協調者出問題,那麼這些被阻塞的資源有可能就一直不被釋放了,須要額外的介入。

2PC相對來講是最簡單的事務模型,但缺點也更多。其它缺點諸如:在某些場景下的數據不一致(參與者與協調者共同與「提交」環節掛了)、阻塞範圍過大等問題。

02 三階段提交(3PC)[6]

圖片來源於網絡,版權歸原做者全部

3PC的出現就是經過增長複雜度(性能也所以下降)來解決或優化2PC中的一部分問題。本質的變化就是在2PC的「請求提交」以後增長了一個「準備提交」環節,以增長每一個參與者須要等待其它的參與者確認後方可進行具體的操做。

  • 「阻塞」這個動做延後到這個「準備提交」環節再作,使得阻塞範圍縮小爲2PC的2/3(圖中背景黃色和綠色部分)。正如上面的例子,在交換戒指以前增長了把戒指交給牧師的動做。
  • 同時還解決了協調者的單點問題。故障恢復或者新接替的協調者,能夠利用「準備提交」產生的狀態結果,來做爲參與者和協調者在「提交」出現故障恢復後的界定依據。仍是前面的例子,誇張點,交換戒指的時候我失憶了,意識恢復後我只要看到牧師手掌上託着戒指或者個人手上已經被戴好了戒指,就知道個人妻子已經答應了,我只要繼續給她作帶戒指這個事就行了。
  • 新引入了timeout機制,在發生超時執行默認約定,避免了永久阻塞,也所以對多個參與者下的100%數據一致性做出了妥協。好比,協調者在向參與者A發送「doCommit」時timeout了,會引起廣播「abort」,可是這個「abort」又未能投遞到參與者B,致使參與者B執行了「ACK」後的timeout默認約定「commit」。

03 TCC

在國內,因爲阿里的光環加持下TCC好像更火,風頭蓋過了2PC和3PC。其本質上是另闢蹊徑達到了和3PC相似的效果。

圖片來源於網絡,版權歸原做者全部

  • 經過運用本地事務代替了全局事務,使得能夠不須要協調者的存在,避免了協調者的單點問題
  • 3PC中協調者的另外一個做用:故障恢復後的數據一致性。在TTC裏經過事務日誌來確保

這個概念最初是由Pat Helland於2007年提出的[7],那時還叫「Tentative-Confirmation-Cancellation」,在2008年的軟件開發2.0技術大會上支付寶CTO(程立)將其在國內推廣開來。

以上這三種就是主流的DTS(Distributed Transaction Service)框架。值得一提的是,無論是3PC仍是TCC,只要涉及到故障恢復或者重試機制,那麼「冪等性」問題必需要提上來了。好比3PC中「提交」階段某個參與者和協調者同時掛了,可是這個參與者在掛以前已經作了commit操做。那麼故障恢復後其實沒人知道它是否執行過了commit,協調者只會爲了能100%確保commit指令被送達,又會發起一次commit通知,這時候若是沒有作好「冪等性」就會發生重複commit的問題。

下面聊聊以「BASE」理論爲基礎的解決方案。

01 異步消息——本地消息表

圖片描述

這種實現方式的思路,源於ebay,與提出BASE理論在同一篇論文中[4]。設計思想是將遠程分佈式事務拆分紅一系列的本地事務,藉助關係型數據庫中的表便可實現。

02 異步消息——不支持事務的MQ

圖片描述

其實大部分的MQ都是不支持事務的,因此咱們須要本身想辦法解決可能出現的MQ消息未能成功投遞出去的問題。有個便宜能夠撿的是,若是需投遞的MQ消息條數僅有1的話,能夠將本地事務的commit放於消息投遞以後便可避免此問題。僞代碼以下:

try{    
    beginTrans();        
    modifyLocalData1();    
    modifyLocalData2();        
    deliverMessageToMQ();        
    commitTrans(); 
}catch(Exception ex){        
    rollbackTrans(); 
}

03 異步消息——支持事務的MQ

圖片描述

據我所知,目前惟一支持事務的MQ框架是RockerMQ,而且於近期纔開源了事務部分實現,《RocketMQ 4.3正式發佈,支持分佈式事務》(http://www.infoq.com/cn/news/...)。這樣的確能省不少事~,直接放一張阿里方面給出的圖感覺一下實現細節。

圖片來源於網絡,版權歸原做者全部(點擊圖片可查看大圖)

不過其實有一個疑點我沒有去驗證,有知道的小夥伴們能夠留言下,就是RocketMQ是否有防止consumer(上圖中的訂閱方)在消費完成後發送的ACK丟失的機制。若是能達到這點,對於consumer內部的方法冪等性需求就低了不少。

04 Saga

圖片描述

Saga是1987年就提出的概念[8],核心是:

  • 將一個分佈式事務拆分爲多個本地事務,而且擊鼓傳花給下一個,不用阻塞本地事務等待響應。且容許嵌套至多一層子事務。
  • 除了最後一個參與者以外,都須要定義一個「回滾」接口,便於在遇到沒法進行下去的狀況下撤銷以前上游系統的修改。固然這裏的撤銷除了Update還能夠是衝抵類的操做。

Saga原則上是個鏈式的「長活事務」,整個處理耗時可能會很長。因此能夠經過增長save point(保存點,相似於遊戲裏的存檔),便於故障恢復和提速,如向前恢復(重試)和向後恢復(回滾)。不過,也能夠並行多個子事務,但通常在運用中心節點的Saga模式中,如圖。

圖片描述

只是在咱們打破了鏈式規則後必需要額外確保執行了「回滾」以後再接收到「正向請求」,等於「請求無效」的效果。中心節點模式還有一個比較大的好處是可以更好的避免事務之間的循環依賴關係。

05 Gossip協議

額外提一下,這個實際上是一個具體的、運用BASE理論實現的協議,藉由Cassandra的熱火而讓更多人知道了。這協議通常會用於數據複製、P2P拓撲構造、故障探測等。

看這些案例咱們能夠發現,基於「CAP」的解決方案都是在線的,而「Base」是容許離線的。比如前者是,累倒了必須得立刻爬起來繼續幹貨,要否則就是失敗。然後者是,慢慢來,只要最終能幹完。

無論怎樣,若是每一個解決方案中增長「重試」和「回滾」會大大提高程序的自我修正能力,以下降須要人爲介入的比例。識別是否須要人爲介入的方式就是相似於「對帳」的機制,這個機制就是兜底的。最後還須要作一道選擇題來防止混亂:確保參與者的接口符合「冪等性」,或者在中間件裏作到「正好一次(Exactly-once)」。

這些基於「BASE」的解決方案都是能夠做爲「CAP」解決方案出現問題時的PlanB來用的,起到補充做用。固然,如非必要,能夠優先考慮基於「BASE」的方案,畢竟這纔是自然易伸縮的,天然也能帶來更好的性能。

5、結語

解決方案如此多,因此無論咱們是架構師、仍是在成爲架構師的路上,甚至在平常生活中,都須要養成Balance的習慣,找到那個最適合的方案

最後還有一招終極大法 —— 減小冗餘。

是亦彼也,彼亦是也,彼亦一是非,此亦一是非。
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp——莊子

「事物都具備兩面性」,因此,在選擇走向分佈式以前,慎重考慮下是否有必要,以避免給本身徒增麻煩

論文可後臺直接回復關鍵字「一致性」,打包下載。下篇將開啓「高可用」主題,敬請期待~

微信後臺回覆「一致性」關鍵字,可打包下載喲~
[1] Distributed TP: The XA Specification , X/Open Company Ltd. , 1991
連接: https://publications.opengrou...
[2] Harvest, Yield, and Scalable Tolerant Systems, Armando Fox , Eric Brewer, 1999
連接: https://cs.uwaterloo.ca/~brec...
[3] Brewer’s Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web, Seth Gilbert, Nancy Lynch, 2002
連接: https://pdfs.semanticscholar....
[4] Base: An Acid Alternative, Dan Pritchett, 2008
連接: http://delivery.acm.org/10.11...
[5] Consensus Protocols: Two-Phase Commit, Henry Robinson, 2008
連接: http://the-paper-trail.org/bl...
[6] Consensus Protocols: Three-phase Commit, Henry Robinson, 2008
連接: http://the-paper-trail.org/bl...
[7] Life beyond Distributed Transactions:an Apostate’s Opinion, 2007
連接: https://cs.brown.edu/courses/...
[8] Sagas, Hector Garcaa-Molrna & Kenneth Salem, 1987
連接: https://www.cs.cornell.edu/an...
做者:Zachary( 我的微信號:Zachary-ZF
微信公衆號(首發): 跨界架構師。<-- 點擊查閱近期熱門文章
按期發表原創內容: 架構設計丨分佈式系統丨產品丨運營丨一些深度思考
掃碼加入小圈子 ↓

圖片描述

相關文章
相關標籤/搜索