在微服務架構中,每個服務都是獨立且自治的,每個服務都有自己的資料庫系統並維護著自身的資料庫交易實作。當業務流程需要跨多個服務時,便會面臨分散式交易(Distributed Transactions)的難題。分散式交易是指在多個獨立的系統或服務中進行的交易,這些交易需要保證要麼全部成功,要麼全部失敗,以保證資料的一致性。
然而,由於微服務間的通訊往往不是不可靠的,並且各個服務之間可能存在網路延遲和故障,因此在微服務架構中實現分散式交易是具有挑戰性的。這些挑戰不僅來自於微服務間的通信不可靠和網絡延遲,還來自於系統的複雜性和不確定性。以本系列文章的例子來看,在建立訂單的業務邏輯中由許多微服務組成,可能需要涉及到多個微服務的相互配合。
首先,訂單服務需要創建一個新訂單;其次,庫存服務需要檢查並更新庫存;最後,支付服務需要處理支付交易。在這個過程中,如果任何一個步驟失敗,都需要能夠恢復到交易開始之前的狀態,以保證資料的一致性。
而分散式交易有幾種常用解決方案,如:2PC(Two-Phase Commit)、3PC(Three-Phase Commit)和 Saga 模式。
二階段提交是一種分散式系統中確保交易原子性的協議,它將交易的提交過程分為兩個階段,以確保所有參與的節點都能達成一致。各個節點只負責執行服務內的本地交易。分散式交易將分為兩階段執行:
投票階段:
提交階段:
三階段提交是二階段提交協議的一個改進版本,它透過加入一個額外的階段來減少系統的阻塞和提高分散式交易的效率:
準備階段 (Pre-Commit Phase):
CanCommit
訊息,詢問它們是否可以提交交易。Yes
給協調器;如果操作失敗,它們回覆 No
給協調器。提交階段 (Commit Phase):
Yes
,它會進入提交階段,向所有參與節點發送 PreCommit
訊息,並等待它們的確認。
PreCommit
訊息後,節點會鎖定交易所需的資源以防止其他操作干擾,並向協調器回覆 Ack
。如果在此階段有任何節點回覆 Abort
,或者協調器在指定時間內未收到所有的 Ack
訊息,那麼它就會向所有節點發送 Abort
進行還原。Ack
訊息後,向它們發送 DoCommit
訊息,指示它們完成交易。DoCommit
訊息後,將立刻完成交易並釋放資源,並向協調器回覆 Done
訊息。如果任何節點在此階段失敗,協調器將會指揮節點進行還原。三階段提交透過增加一個額外的 Pre-Commit 階段,嘗試減少因網絡分割或節點故障而導致的系統阻塞,並提供更高的效率和可靠性。
Saga 模式[1]是一種非常適合於微服務架構的分散式交易解決方案,它將長期的交易拆分為小步驟的交易,每個交易都有一個相應的補償交易,用於在某個步驟失敗時還原之前的改變。在微服務架構中,我們有兩種開發模式可以實現 Saga 分別是服務編排(Choreography)與服務協作(Orchestration)模式。
服務編排與服務協作的差異可以至第二章-微服務與它們的溝通管道 參閱詳細介紹。
在 Saga 模式中交易由交易序列(Transaction Sequence)所組成,如:T1, T2, …, Tn。在交易序列中的每一個步驟(Step)將是服務內的資料庫交易。Saga在補償處理的機制上,在定義交易序列(Transaction Sequence)的同時,也會定義補償序列(Compensate Sequence),如:C1, C2, …, Cn。當交易步驟執行失敗時,Saga 機制將會依照宣告好的補償步驟往回進行補償。
相對於其他模式,Saga 提供了一種更為靈活的解決方案。協作型的 Saga 的中央協作器將負責保障所有交易內容按照預定的順序執行,並在出現錯誤時觸發相應的補償交易,這種模式大大降低了系統的復雜度。
而 Saga 在資料庫的 ACID 理論中僅滿足 ACD 並不保障 I(隔離性),因此我們可能會發生下列的交易異常:
我們可以以下列策略應對問題:
2008年,大型電子商務公司eBay架構師 Pritchett 提出了新的資料庫理論「BASE」[2]。相較於ACID強制保持一致性,BASE更著重於接受資料庫一致性將處於不斷變化的狀態,同時也能更易於管理資料庫,達到ACID無法獲得的擴充性。BASE為以下幾個特性組成,分別是:
BASE理論反映了在分散式環境中實現高可用性和擴展性的需求,它放寬了一致性的要求,以實現更高的可用性。這是分散式系統和微服務架構中常見的一種取舍。
總的來說,Saga 設計模式為微服務架構中的分散式交易提供了一個較為實用和靈活的解決方案。它允許系統在出現錯誤時進行有效的補償,從而保證了資料的一致性,並降低了復雜的協調和通訊開銷;然而,它也帶來了一些挑戰,例如可能的交易異常和必要的補償邏輯設計。在採用Saga模式時,開發人員需要仔細考慮和設計每個微服務的交易和補償機制,以確保系統的健壯性和可靠性。
在實際應用中,可能會根據具體的系統架構和業務需求,將 Saga 模式與其他分散式交易解決方案(如2PC或3PC)結合使用,以達到最佳的效果。
[1] Hector Garcia-Molina and Kenneth Salem, "Sagas", ACM Sigmod Record, vol. 16, no. 3, pp. 249-259, 1987.
[2] D. Pritchett, " BASE: An Acid Alternative: In partitioned databases, trading some consistency for availability can lead to dramatic improvements in scalability," Queue, vol. 6, no. 3, pp. 48–55, May 2008.