分佈式事物的前世今生和姻緣化解(完整版)

 

 

一、分佈式事物由來

微服務的發展導致的問題

微服務倡導將複雜的單體應用拆分爲若干個功能簡單、鬆耦合的服務,這樣可以降低開發難度、增強擴展性、便於敏捷開發。當前被越來越多的開發者推崇,很多互聯網行業巨頭、開源社區等都開始了微服務的討論和實踐。Hailo有160個不同服務構成,NetFlix有大約600個服務。國內方面,阿里巴巴、騰訊、360、京東、58同城等很多互聯網公司都進行了微服務化實踐。當前微服務的開發框架也非常多,比較著名的有Dubbo、SpringCloud、thrift 、grpc等。

雖然微服務現在如火如荼,但對其實踐其實仍處於探索階段。很多中小型互聯網公司,鑑於經驗、技術實力等問題,微服務落地比較困難。如著名架構師Chris Richardson所言,目前存在的主要困難有如下幾方面:

1)單體應用拆分爲分佈式系統後,進程間的通訊機制和故障處理措施變的更加複雜。

2)系統微服務化後,一個看似簡單的功能,內部可能需要調用多個服務並操作多個數據庫實現,服務調用的分佈式事務問題變的非常突出。

3)微服務數量衆多,其測試、部署、監控等都變的更加困難。

隨着RPC框架的成熟,第一個問題已經逐漸得到解決。例如dubbo可以支持多種通訊協議,springcloud可以非常好的支持restful調用。對於第三個問題,隨着docker、devops技術的發展以及各公有云paas平臺自動化運維工具的推出,微服務的測試、部署與運維會變得越來越容易。

而對於第二個問題,現在還沒有通用方案很好的解決微服務產生的事務問題。分佈式事務已經成爲微服務落地最大的阻礙,也是最具挑戰性的一個技術難題。

二、分佈式基本理論

1、CAP理論

在分佈式系統中,一致性(Consistency)、可用性(Availability)和分區容錯性(Partition Tolerance)3 個要素最多隻能同時滿足兩個,不可兼得。其中,分區容錯性又是不可或缺的。

  • 一致性:分佈式環境下多個節點的數據是否強一致。

  • 可用性:分佈式服務能一直保證可用狀態。當用戶發出一個請求後,服務能在有限時間內返回結果。

  • 分區容錯性:特指對網絡分區的容錯性。

舉例:

默認優先選擇AP,弱化C。Cassandra、Dynamo 等。

默認優先選擇CP,弱化A。HBase、MongoDB ,Redis等作爲數據庫必須首要滿足就是一致性,否則沒有意義,所以寧可等待查詢降低可用性,也不會返回錯誤數據。

默認優先選擇AC,弱化C。相對於現在的電商,可用性相比強一致性更爲重要,所以搶購場景中會出現明明有存貨,點進去支付的時候又沒有了,他們要求的是最終一致性。

2、BASE理論

核心思想:

  1. 基本可用(Basically Available):指分佈式系統在出現故障時,允許損失部分的可用性來保證核心可用。

  2. 軟狀態(Soft State):指允許分佈式系統存在中間狀態,該中間狀態不會影響到系統的整體可用性。

  3. 最終一致性(Eventual Consistency):指分佈式系統中的所有副本數據經過一定時間後,最終能夠達到一致的狀態。

三、一致性理論

分佈式事務的目的是保障分庫數據一致性,而跨庫事務會遇到各種不可控制的問題,如個別節點永久性宕機,像單機事務一樣的ACID是無法奢望的。另外,業界著名的CAP理論也告訴我們,對分佈式系統,需要將數據一致性和系統可用性、分區容忍性放在天平上一起考慮。

 

簡單介紹下ACID,關係型數據庫必備特性  

(摘自維基百科)

  1. Atomicity(原子性):一個事務(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢復(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。即,事務不可分割、不可約簡。

  2. Consistency(一致性):在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設約束、觸發器、級聯回滾。

  3. Isolation(隔離性):數據庫允許多個併發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致數據的不一致。事務隔離分爲不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)。

  4. Durability(持久性):事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。

兩階段提交協議(簡稱2PC)是實現分佈式事務較爲經典的方案,但2PC 的可擴展性很差,在分佈式架構下應用代價較大,eBay 架構師Dan Pritchett 提出了BASE 理論,用於解決大規模分佈式系統下的數據一致性問題。BASE 理論告訴我們:可以通過放棄系統在每個時刻的強一致性來換取系統的可擴展性。

1、一致性模型

  1. 強一致性:數據更新成功後,任意時刻所有副本中的數據都是一致的,一般採用同步的方式實現。

  2. 弱一致性:數據更新成功後,系統不承諾立即可以讀到最新寫入的值,也不承諾具體多久之後可以讀到。

  3. 最終一致性:弱一致性的一種形式,數據更新成功後,系統不承諾立即可以返回最新寫入的值,但是保證最終會返回上一次更新操作的值。

四、分佈式事物的解決方案

關於分佈式事務,工程領域主要討論的是強一致性和最終一致性的解決方案。典型方案包括:

  1. 兩階段提交(2PC, Two-phase Commit)方案

  2. TCC 補償模式

  3. 基於消息

  4. 其他

1、2PC方案——強一致性

2PC的核心原理是通過提交分階段和記日誌的方式,記錄下事務提交所處的階段狀態,在組件宕機重啓後,可通過日誌恢復事務提交的階段狀態,並在這個狀態節點重試,如Coordinator重啓後,通過日誌可以確定提交處於Prepare還是PrepareAll狀態,若是前者,說明有節點可能沒有Prepare成功,或所有節點Prepare成功但還沒有下發Commit,狀態恢復後給所有節點下發RollBack;若是PrepareAll狀態,需要給所有節點下發Commit,數據庫節點需要保證Commit冪等。

2PC方案的問題:

  1. 同步阻塞。

  2. 數據不一致。

  3. 單點問題。

升級的3PC方案旨在解決這些問題,主要有兩個改進:

  1. 增加超時機制。

  2. 兩階段之間插入準備階段。

但三階段提交也存在一些缺陷,要徹底從協議層面避免數據不一致,可以採用Paxos或者Raft算法。2,3PC提交方案應用非常廣泛,幾乎所有商業OLTP數據庫都支持XA協議。但是兩階段提交方案鎖定資源時間長,對性能影響很大,而且XA提交對於業務相對透明,不利於開發者對業務的充分掌控。基本不適合解決微服務事務問題。

2、TCC (Try-Confirm-Cancel)補償模式——最終一致性

TCC方案在電商、金融領域落地較多。TCC方案其實是兩階段提交的一種改進。其將整個業務邏輯的每個分支顯式的分成了Try、Confirm、Cancel三個操作。Try部分完成業務的準備工作,confirm部分完成業務的提交,cancel部分完成事務的回滾。基本原理如下圖所示。

事務開始時,業務應用會向事務協調器註冊啓動事務。之後業務應用會調用所有服務的try接口,完成一階段準備。之後事務協調器會根據try接口返回情況,決定調用confirm接口或者cancel接口。如果接口調用失敗,會進行重試。

TCC方案讓應用自己定義數據庫操作的粒度,使得降低鎖衝突、提高吞吐量成爲可能。 當然TCC方案也有不足之處,集中表現在以下兩個方面:

  1. 對應用的侵入性強。業務邏輯的每個分支都需要實現try、confirm、cancel三個操作,應用侵入性較強,改造成本高。

  2. 實現難度較大。需要按照網絡狀態、系統故障等不同的失敗原因實現不同的回滾策略。爲了滿足一致性的要求,confirm和cancel接口必須實現冪等。

上述原因導致TCC方案大多被研發實力較強、有迫切需求的大公司所採用。微服務倡導服務的輕量化、易部署,而TCC方案中很多事務的處理邏輯需要應用自己編碼實現,複雜且開發量大,但是相比XA階段提交對於業務掌控度更高,這點在金融電商方面尤其重要。

3、基於消息——最終一致性

消息一致性方案是通過消息中間件保證上、下游應用數據操作的一致性。基本思路是將本地操作和發送消息放在一個事務中,保證本地操作和消息發送要麼兩者都成功或者都失敗。下游應用向消息系統訂閱該消息,收到消息後執行相應操作。

消息方案從本質上講是將分佈式事務轉換爲兩個本地事務,然後依靠下游業務的重試機制達到最終一致性。基於消息的最終一致性方案對應用侵入性也很高,應用需要進行大量業務改造,成本較高。

4、其他

阿里的GTS,eBay的事件隊列方案,騰訊的CMQ等,有興趣的童鞋可以自己擴展下。

四、選擇建議

在面臨數據一致性問題的時候,首先要從業務需求的角度出發,確定我們對於3 種一致性模型的接受程度,再通過具體場景來決定解決方案。

從應用角度看,分佈式事務的現實場景常常無法規避,在有能力給出其他解決方案前,2PC也是一個不錯的選擇。

對購物轉賬等電商和金融業務,中間件層的2PC最大問題在於業務不可見,一旦出現不可抗力或意想不到的一致性破壞,如數據節點永久性宕機,業務難以根據2PC的日誌進行補償。金融場景下,數據一致性是命根,業務需要對數據有百分之百的掌控力,建議使用TCC這類分佈式事務模型,或基於消息隊列的柔性事務框架,這兩種方案都在業務層實現,業務開發者具有足夠掌控力,可以結合SOA框架來架構,包括Dubbo、Spring Cloud等。

關注小碼農訂閱號!拉你進羣一起交流!加我微信號拉你進java菜雞交流羣,java大廠內推羣,java進階高手羣!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章