微服務的一致性問題


1、微服務架構的數據一致性問題

以電商平台為例,當用戶下單並支付后,系統需要修改訂單的狀態並且增加用戶積分。由於系統采用的是微服務架構,分離出了支付服務、訂單服務和積分服務,每個服務都有獨立數據庫做數據存儲。當用戶支付成功后,無論是修改訂單狀態失敗還是增加積分失敗,都會造成數據的不一致。

 

為了解決例子中的數據一致性問題,一個最直接的辦法就是考慮數據的強一致性。那么如何保證數據的強一致性呢?我們從關系型數據庫的 ACID 理論說起。

關系型數據庫具有解決復雜事務場景的能力,關系型數據庫的事務滿足 ACID 的特性。

Atomicity:原子性(要么都做,要么都不做)

Consistency:一致性(數據庫只有一個狀態,不存在未確定狀態)

Isolation:隔離性(事務之間互不干擾)

Durability: 永久性(事務一旦提交,數據庫記錄永久不變)

具有 ACID 特性的數據庫支持數據的強一致性,保證了數據本身不會出現不一致。

然而微服務架構下,每個微服務都有自己的數據庫,導致微服務架構的系統不能簡單地滿足 ACID,我們就需要尋找微服務架構下的數據一致性解決方案。

微服務架構的系統本身是一種分布式系統,而本文討論的問題其實也就是分布式事務之數據一致性的問題,我們來聊聊分布式系統的 CAP 理論和 BASE 理論。

CAP 是指在一個分布式系統下, 包含三個要素:Consistency(一致性)、Availability(可用性)、Partition tolerance(分區容錯性),並且三者不可得兼。

C:Consistency,一致性,所有數據變動都是同步的。

A:Availability,可用性,即在可以接受的時間范圍內正確地響應用戶請求。

P:Partition tolerance,分區容錯性,即某節點或網絡分區故障時,系統仍能夠提供滿足一致性和可用性的服務

關系型數據庫 單節點 保證了數據強一致性(C)和可用性(A),但是卻無法保證分區容錯性(P)。

然而在分布式系統下,為了保證模塊的分區容錯性(P),只能在數據強一致性(C)和可用性(A)之間做平衡。具體表現為在一定時間內,可能模塊之間數據是不一致的,但是通過自動或手動補償后能夠達到最終的一致。

BASE 理論主要是解決 CAP 理論中分布式系統的可用性和一致性不可兼得的問題。BASE 理論包含以下三個要素:

BA:Basically Available,基本可用。

S:Soft State,軟狀態,狀態可以有一段時間不同步。

E:Eventually Consistent,最終一致,最終數據是一致的就可以了,而不是時時保持強一致。

BASE 模型與 ACID 不同,滿足 CAP 理論,通過 犧牲強一致性來保證系統可用性。由於犧牲了強一致性,系統在處理請求的過程中,數據可以存在短時的不一致。

系統在處理業務時,記錄每一步的臨時狀態。當出現異常時,根據狀態判斷是否繼續處理請求或者退回原始狀態,從而達到數據的最終一致。

例如,在上面的案例中,支付成功,訂單也成功,但增加積分失敗,此時,不應回滾支付和訂單,而應通過一些 補償方法 來讓積分得以正確地增加。后面會講到具體的實現方法。

在分享我們的分布式事務實踐方案之前,先看看早期解決分布式事務問題的二階段提交協議。

2、二階段提交協議

X/Open DTP(Distributed Transaction Process)是一個分布式事務模型,此模型主要使用二階段提交(2PC,Two-Phase-Commit)來保證分布式事務的完整性。在這個模型里面,有三個角色:

AP:Application,應用程序,業務層。

RM:Resource Manager,資源管理器,關系型數據庫或支持 XA 接口(XA 規范是 X/Open 組織定義的分布式事務規范)的組件。

TM: Transaction Manager ,事務管理器,負責各個 RM 的提交和回滾。

當應用程序(AP)調用了事務管理器(TM)的提交方法時,事務的提交分為兩個階段實行。

2.1、第一階段(准備階段)

 

TM 通知所有參與事務的各個 RM,給每個 RM 發送 prepare 消息。

RM 接收到消息后進入准備階段后,要么直接返回失敗,要么創建並執行本地事務,寫本地事務日志(redo 和 undo 日志),但是 不提交(此處只保留最后一步耗時最少的提交操作給第二階段執行)。

2.2、第二階段(提交 / 回滾階段)

 

TM 收到 RM 准備階段的失敗消息或者獲取 RM 返回消息超時,則直接給 RM 發送回滾(rollback)消息,否則發送提交(commit)消息。

RM 根據 TM 的指令執行提交或者回滾,執行完成后釋放所有事務處理過程中使用的鎖(最后階段釋放鎖)。

 

2.3、二階段提交的利弊

優點

2PC 提供了一套完整的分布式事務的解決方案,遵循事務嚴格的 ACID 特性。

缺點

TM 通過 XA 接口與各個 RM 之間進行數據交互,從第一階段的准備階段,業務所涉及的數據就被鎖定,並且鎖定跨越整個提交流程。在高並發和涉及業務模塊較多的情況下對數據庫的性能影響較大。

二階段是 反可伸縮模式 的,業務規模越大,涉及模塊越多,局限性越大,系統可伸縮性越差。

在技術棧比較雜的分布式應用中,存儲組件有很多 不支持 XA 協議。

二階段的諸多弊端,導致分布式系統下無法直接使用此方案來解決數據一致性問題,但它提供了解決分布式系統下數據一致性問題的思路。。

下面就通過案例來分享我們是如何保證微服務架構的數據一致性的。

1、可靠事件模式

 

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

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

 

可靠事件模式在於保證可靠事件投遞避免重復消費,可靠事件投遞定義為

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

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

 

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

 

2補償模式

 

為了描述方便,這里先定義兩個概念:

 

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

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

 

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

 

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

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

 

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

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

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

 

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

 

3TCC模式(Try-Confirm-Cancel

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

 

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

 

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

 

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

冪等性

在編程中一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。

冪等函數,或冪等方法,是指可以使用相同參數重復執行,並能獲得相同結果的函數。這些函數不會影響系統狀態,也不用擔心重復執行會對系統造成改變。

在事務提交失敗會重復提交達到最大重復次數時返回失敗的 設計中  保持冪等性是尤為重要的

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM