微服務架構下的事務一致性保證

【轉】微服務架構下的數據一致性保證(一)

今天分享第一篇,主要內容包括:

 

1.傳統使用本地事務和分佈式事務保證一致性。

2.傳統分佈式事務不是微服務中一致性的最佳選擇。

3.微服務架構中應滿足數據最終一致性原則。

4.微服務架構實現最終一致性的三種模式。

5.對賬是最後的終極防線。

一、傳統使用本地事務和分佈式事務保證一致性

 

傳統單機應用一般都會使用一個關係型數據庫,好處是應用可以使用 ACID transactions。爲保證一致性我們只需要:開始一個事務,改變(插入,刪除,更新)很多行,然後提交事務(如果有異常時回滾事務)。更進一步,藉助開發平臺中的數據訪問技術和框架(如Spring),我們需要做的事情更少,只需要關注數據本身的改變。

 

隨着組織規模不斷擴大,業務量不斷增長,單機應用和數據庫已經不足以支持龐大的業務量和數據量,這個時候需要對應用和數據庫進行拆分,就出現了一個應用需要同時訪問兩個或兩個以上的數據庫情況。開始我們用分佈式事務來保證一致性,也就是我們常說的兩階段提交協議(2PC)。

 

本地事務和分佈式事務現在已經非常成熟,相關介紹很豐富,此處不多作討論。

 

二、傳統分佈式事務不是微服務中一致性的最佳選擇

 

首先,對於微服務架構來說,數據訪問變得更加複雜,這是因爲數據都是微服務私有的,唯一可訪問的方式就是通過API。這種打包數據訪問方式使得微服務之間鬆耦合,並且彼此之間獨立非常容易進行性能擴展。

其次,不同的微服務經常使用不同的數據庫。應用會產生各種不同類型的數據,關係型數據庫並不一定是最佳選擇。

 

例如,某個產生和查詢字符串的應用採用Elasticsearch的字符搜索引擎;某個產生社交圖片數據的應用可以採用圖數據庫,例如,Neo4j;

基於微服務的應用一般都使用SQL和NoSQL結合的模式。但是這些非關係型數據大多數並不支持2PC。

可見在微服務架構中已經不能選擇分佈式事務了。

 

三、微服務架構中應滿足數據最終一致性原則 

依據CAP理論,必須在可用性(availability)和一致性(consistency)之間做出選擇。如果選擇提供一致性需要付出在滿足一致性之前阻塞其他併發訪問的代價。這可能持續一個不確定的時間,尤其是在系統已經表現出高延遲時或者網絡故障導致失去連接時。

 

依據目前的成功經驗,可用性一般是更好的選擇,但是在服務和數據庫之間維護數據一致性是非常根本的需求,微服務架構中選擇滿足最終一致性

當然選擇了最終一致性,就要保證到最終的這段時間要在用戶可接受的範圍之內。

 

那麼我們怎麼實現最終一致性呢?

 

四、微服務架構實現最終一致性的三種模式

 

從一致性的本質來看,是要保證在一個業務邏輯中包含的服務要麼都成功,要麼都失敗。那我們怎麼選擇方向呢?保證成功還是保證失敗呢?

我們說業務模式決定了我們的選擇。實現最終一致性有三種模式:可靠事件模式、業務補償模式、TCC模式。

 

1) 可靠事件模式

可靠事件模式屬於事件驅動架構,當某件重要事情發生時,例如更新一個業務實體,微服務會向消息代理髮佈一個事件。消息代理會向訂閱事件的微服務推送事件,當訂閱這些事件的微服務接收此事件時,就可以完成自己的業務,也可能會引發更多的事件發佈。

1. 如訂單服務創建一個待支付的訂單,發佈一個“創建訂單”的事件。

 

2.支付服務消費“創建訂單”事件,支付完成後發佈一個“支付完成”事件。

3.訂單服務消費“支付完成”事件,訂單狀態更新爲待出庫。

從而就實現了完成的業務流程。

這個過程可能導致出現不一致的地方在於:某個微服務在更新了業務實體後發佈事件卻失敗;雖然微服務發佈事件成功,但是消息代理未能正確推送事件到訂閱的微服務;接受事件的微服務重複消費了事件。

 

可靠事件模式在於保證可靠事件投遞避免重複消費

可靠事件投遞定義爲:

(a)每個服務原子性的業務操作和發佈事件

(b)消息代理確保事件傳遞至少一次。 

避免重複消費要求服務實現冪等性,如支付服務不能因爲重複收到事件而多次支付。

 

2) 補償模式

爲了描述方便,這裏先定義兩個概念:

業務異常:業務邏輯產生錯誤的情況,比如賬戶餘額不足、商品庫存不足等。

技術異常:非業務邏輯產生的異常,如網絡連接異常、網絡超時等。

補償模式使用一個額外的協調服務來協調各個需要保證一致性的微服務,協調服務按順序調用各個微服務,如果某個微服務調用異常(包括業務異常和技術異常)就取消之前所有已經調用成功的微服務

 

補償模式建議僅用於不能避免出現業務異常的情況,如果有可能應該優化業務模式,以避免要求補償事務。如賬戶餘額不足的業務異常可通過預先凍結金額的方式避免,商品庫存不足可要求商家準備額外的庫存等。

我們通過一個實例來說明補償模式,一家旅行公司提供預訂行程的業務,可以通過公司的網站提前預訂飛機票、火車票、酒店等。

 

假設一位客戶規劃的行程是,(1)上海-北京6月19日9點的某某航班,(2)某某酒店住宿3晚,(3)北京-上海6月22日17點火車。在客戶提交行程後,旅行公司的預訂行程業務按順序串行的調用航班預訂服務、酒店預訂服務、火車預訂服務。最後的火車預訂服務成功後整個預訂業務纔算完成。

如果火車票預訂服務沒有調用成功,那麼之前預訂的航班、酒店都得取消。取消之前預訂的酒店、航班即爲補償過程。

 

需要注意的是酒店的取消預訂、航班的取消預訂同樣不能保證一定成功,所以補償過程往往也同樣需要實現最終一致性,需要保證取消服務至少被調用一次和取消服務必須實現冪等性。

 

我們應該儘可能通過設計避免採用補償方式,比如上面的例子中,在預訂火車票失敗的時候可以提示客戶更改其他的時間。

 

 3) TCC模式(Try-Confirm-Cancel)

 

一個完整的TCC業務由一個主業務服務和若干個從業務服務組成,主業務服務發起並完成整個業務活動,TCC模式要求從服務提供三個接口:Try、Confirm、Cancel。

例如從服務有2個:

1) Try:完成所有業務檢查

預留必須業務資源

 

2) Confirm:真正執行業務

不作任何業務檢查

只使用Try階段預留的業務資源

Confirm操作滿足冪等性

 

3) Cancel:

釋放Try階段預留的業務資源

Cancel操作滿足冪等性

整個TCC業務分成兩個階段完成。

第一階段:主業務服務分別調用所有從業務的try操作,並在活動管理器中登記所有從業務服務。當所有從業務服務的try操作都調用成功或者某個從業務服務的try操作失敗,進入第二階段。

第二階段:活動管理器根據第一階段的執行結果來執行confirm或cancel操作。如果第一階段所有try操作都成功,則活動管理器調用所有從業務活動的confirm操作。否則調用所有從業務服務的cancel操作。

需要注意的是第二階段confirm或cancel操作本身也是滿足最終一致性的過程,在調用confirm或cancel的時候也可能因爲某種原因(比如網絡)導致調用失敗,所以需要活動管理支持重試的能力,同時這也就要求confirm和cancel操作具有冪等性。

 

五、對賬是最後的終極防線

如果有些業務由於瞬時的網絡故障或調用超時等問題,通過上文所講的3種模式一般都能得到很好的解決。但是在當今雲計算環境下,很多服務是依賴於外部系統的可用性情況,在一些重要的業務場景下還需要週期性的對賬來保證真實的一致性。比如支付系統和銀行之間每天日終是都會有對賬過程。

轉:https://mp.weixin.qq.com/s?__biz=MzI5MDEzMzg5Nw==&mid=2660392782&idx=1&sn=d28e43bf6f7cf140eed9fffcf2f29e86&scene=1&srcid=0811qaoc12E47x6vDVNkynBO#rd


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