1. 程式人生 > >分散式事務最終一致性常用方案

分散式事務最終一致性常用方案

  目前的應用系統,不管是企業級應用還是網際網路應用,最終資料的一致性是每個應用系統都要面臨的問題,隨著分散式的逐漸普及,資料一致性更加艱難,但是也很難有銀彈的解決方案,也並不是引入特定的中介軟體或者特定的開源框架能夠解決的,更多的還是看業務場景,根據場景來給出解決方案。根據筆者最近幾年的瞭解,總結了幾個點,更多的應用系統在編碼的時候,更加關注資料的一致性,這樣系統才是健壯的。

一、基礎理論

   目前關於事務的幾大理論包括:ACID事務特性,CAP分散式理論,以及BASE等。ACID在資料庫事務中體現CAP和BASE則是分散式事務的理論,結合業務系統,例如訂單管理,例如倉儲管理等,可以借鑑這些理論,從而解決問題。

1、ACID 特性

2、CAP特性

  • C(一致性)一致性是指資料的原子性,在經典的資料庫中通過事務來保障,事務完成時,無論成功或回滾,資料都會處於一致的狀態,在分散式環境下,一致性是指多個節點資料是否一致;
  • A(可用性)服務一直保持可用的狀態,當用戶發出一個請求,服務能在一定的時間內返回結果;
  • P(分割槽容忍性)在分散式應用中,可能因為一些分散式的原因導致系統無法運轉,好的分割槽容忍性,使應用雖然是一個分散式系統,但是好像一個可以正常運轉的整體

3、BASE特性

  • BA: Basic Availability 基本業務可用性;
  • S: Soft state 柔性狀態;
  • E: Eventual consistency 最終一致性;

二、最終一致性的常用做法

1、單資料庫事務

      如果應用系統是單一的資料庫,那麼這個很好保證,利用資料庫的事務特性來滿足事務的一致性,這時候的一致性是強一致性的。對於java應用系統來講,很少直接通過事務的start和commit以及rollback來硬編碼,大多通過spring的事務模板或者宣告式事務來保證;

2、多資料庫事務

     針對多資料庫事務可以根據二階段提交協議,採用spring 3.0 + Atomikos + JTA進行支援;

3、基於事務型訊息佇列的最終一致性

     藉助訊息佇列,在處理業務邏輯的地方傳送訊息,業務邏輯處理成功後,提交訊息,確保訊息是傳送成功的,之後訊息佇列投遞來進行處理,如果成功,則結束,如果沒有成功,則重試,直到成功,不過僅僅適用業務邏輯中,第一階段成功,第二階段必須成功的場景。對應上圖中的C流程。

4、基於訊息佇列+定時補償機制的最終一致性

     前面部分和上面基於事務型訊息的佇列,不同的是,第二階段重試的地方,不再是訊息中介軟體自身的重試邏輯了,而是單獨的補償任務機制。其實在大多數的邏輯中,第二階段失敗的概率比較小,所以單獨獨立補償任務表出來,可以更加清晰,能夠比較明確的直到當前多少任務是失敗的。對應上圖的E流程。

5、非同步回撥機制的引入

     A應用呼叫B,在同步呼叫的返回結果中,B返回成功給到A,一般情況下,這時候就結束了,其實在99.99%的情況是沒問題的,但是有時候為了確保100%,記住最起碼在系統設計中100%,這時候B系統再回調A一下,告訴A,你呼叫我的邏輯,確實成功了。其實這個邏輯,非常類似TCP協議中的三次握手。上圖中的B流程。

6、類似double check機制的確認機制

    還是上圖中非同步回撥的過程,A在同步呼叫B,B返回成功了。這次呼叫結束了,但是A為了確保,在過一段時間,這個時間可以是幾秒,也可以是每天定時處理,再呼叫B一次,查詢一下之前的那次呼叫是否成功。例如A呼叫B更新訂單狀態,這時候成功了,延遲幾秒後,A查詢B,確認一下狀態是否是自己剛剛期望的。上圖中的D流程。

三、分散式事務的缺點

1、二階段提交協議缺點

    兩階段提交涉及到多個節點的網路通訊,通訊時間如果過長,事務的相對時間也就會過長,那麼鎖定資源的時間也就長了.在高併發的服務中,就會存在嚴重的效能瓶勁

 2、訊息佇列

   在高併發的環境中,我們一般會採用訊息佇列來避免分散式事務的執行。

   在使用訊息佇列時,我們需要做到可靠憑證的儲存(分散式事務的訊息),有如下幾種方式:

   以支付寶和餘額寶為例進行說明.

   支付寶完成扣錢的動作時,記錄訊息資料,將訊息資料和業務資料存在同一個資料庫例項中.

Begin Transaction
  update A set amount=amount-1000 where uid=100;
  insert into message(uid,amount,status) values (1,1000,1)
End Transaction
Commit;

將支付寶完成扣錢的訊息及時傳送給餘額寶,餘額寶完成處理後返回成功訊息,支付寶收到訊息後,消除訊息表中對應的訊息記錄,即完成本次扣錢操作.

傳統方式是,我做完了,發你訊息。解決一致性的方案的意思就是,我先發你訊息,我做完了再跟你確認我做完了。這是改進後的有事務的訊息中介軟體。