編輯

共用方式為


Saga 分散式交易模式

Azure

Saga 設計模式藉由協調多個服務之間的交易,協助維護分散式系統中的數據一致性。 傳奇是一連串的本機交易,其中每個服務都會執行其作業,並透過事件或訊息起始下一個步驟。 如果序列中的步驟失敗,Saga 會執行補償交易,以復原完成的步驟,維護數據一致性。

內容和問題

交易 代表可包含多個作業的工作單位。 在交易中,事件 是指影響實體的狀態變更。 命令 封裝執行動作或觸發後續事件所需的所有資訊。

交易必須遵循不可部分完成性、一致性、隔離和持久性 (ACID) 的原則。

  • 不可部分完成性:所有作業都成功或無。
  • 一致性:數據會從一個有效狀態轉換成另一個狀態。
  • 隔離:並行交易會產生與循序交易相同的結果。
  • 持久性:一旦認可,變更即使在失敗中仍會持續發生。

在單一服務中,交易會遵循 ACID 原則,因為它們會在單一資料庫內運作。 不過,在多個服務之間達成 ACID 合規性更為複雜。

微服務架構中的挑戰

微服務架構通常會將 專用資料庫指派給每個微服務,其提供數個優點:

  • 每個服務都會封裝自己的數據。
  • 每個服務都可以針對其特定需求使用最適合的資料庫技術和架構。
  • 每個服務的資料庫獨立調整。
  • 一個服務中的失敗會與其他服務隔離。

儘管有這些優點,但此架構會使跨服務數據一致性複雜化。 傳統資料庫保證,例如 ACID 無法直接適用於多個獨立管理的數據存放區。 由於這些限制,依賴進程間通訊 (IPC) 或傳統交易模型的架構,例如雙階段認可 (2PC) 通訊協定,通常更適合 Saga 模式。

溶液

Saga 模式會將交易分成一系列 本機交易 來管理交易(見圖 1)。

顯示傳奇概觀的圖表。
圖 1. 具有三個服務的傳奇故事。

每個本機交易:

  1. 在單一服務內以不可部分完成的工作。
  2. 更新服務的資料庫。
  3. 透過事件或訊息起始下一個交易。
  4. 如果本機交易失敗,saga 會執行一系列 補償交易, 來反轉先前本機交易所做的變更。

Saga 模式中的重要概念

  • 可補償交易:其他交易可以復原或補償相反效果的交易。 如果傳奇中的步驟失敗,補償交易會復原可補償交易所做的變更。

  • 樞紐交易:樞紐交易可作為傳奇中的「無傳回點」。 一旦樞紐交易成功,可補償的交易(可能無法復原)就不再相關。 所有後續動作都必須完成,系統才能達到一致的最終狀態。 根據傳奇的流程,樞紐交易可能會落入不同的角色:

    • 不可復原(不可編譯):無法復原或重試。

    • 可逆和認可的之間的界限:它可以是最後一個可復原的(可補償)交易,也可以是傳奇中的第一個可重試作業。

  • 可重試的交易:這些交易會遵循樞紐交易。 可重試的交易具有等冪性,並確保saga可以達到其最終狀態,即使發生暫時性失敗也一樣。 它保證傳奇最終會達到一致的狀態。

Saga 實作方法

有兩種常見的saga實作方法,編舞協調流程。 每個方法都有自己的一組挑戰和技術來協調工作流程。

編舞

在編舞中,服務會交換事件,而不需要集中式控制器。 使用編舞時,每個本機交易都會發佈網域事件,以在其他服務中觸發本機交易(請參閱圖 2)。

使用編舞顯示傳奇的圖表。
圖 2. 使用編舞的傳奇。

編舞 的 優點 編舞 的 缺點
適用於少數服務且不需要協調邏輯的簡單工作流程。 新增步驟時,工作流程可能會變得混淆。 很難追蹤哪些傳奇參與者會接聽哪些命令。
協調不需要其他服務。 傳奇參與者之間有迴圈相依性的風險,因為它們必須取用彼此的命令。
不會引入單一失敗點,因為責任會分散到傳奇參與者。 整合測試很困難,因為所有服務都必須執行以模擬交易。

配器

在協調流程中,集中式控制器 (orchestrator) 會處理所有交易,並告知參與者根據事件執行哪些作業。 協調器會執行傳奇要求、儲存和解譯每個工作的狀態,並使用補償交易處理失敗復原(請參閱圖 3)。

使用協調流程顯示傳奇的圖表。
圖 3. 使用協調流程的傳奇。

協調流程 的 優點 協調流程 的 缺點
更適合複雜的工作流程,或在新增服務時使用。 其他設計複雜度需要協調邏輯的實作。
避免迴圈相依性,因為協調器會管理流程。 引進失敗點,因為協調器會管理完整的工作流程。
清楚區分責任可簡化服務邏輯。

問題和考慮

實作 Saga 模式時,請考慮下列幾點:

  • 設計思維轉變:採用Saga模式需要不同的思維,專注於協調交易,並確保跨多個微服務的數據一致性。

  • 偵錯傳奇的複雜度:偵錯傳奇可能相當複雜,特別是隨著參與服務的數目增加。

  • 無法復原的本機資料庫變更:無法回復數據,因為傳奇參與者會將變更認可至其各自的資料庫。

  • 處理暫時性失敗和等冪:系統必須有效處理暫時性失敗,並確保重複相同的作業不會改變結果。 如需詳細資訊,請參閱 等冪訊息處理

  • 監視和追蹤傳奇的需求:監視和追蹤傳奇的工作流程對於維護作業監督至關重要。

  • 補償交易的限制:補償交易可能不一定成功,可能會使系統處於不一致的狀態。

傳奇中潛在的數據異常

數據異常是跨多個服務執行傳奇時可能發生的不一致。 因為每個服務都會管理自己的數據(參與者數據),因此不會跨服務進行內建隔離。 此設定可能會導致數據不一致或持久性問題,例如部分套用的更新或服務之間的衝突。 常見問題包括:

  • 遺失的更新:當某個傳奇修改數據而不考慮另一個傳奇所做的變更時,會導致覆寫或遺失更新。

  • Dirty 會讀取:當傳奇或交易讀取另一個傳奇修改但尚未完成的數據時。

  • 模糊(不可重複)讀取:當傳奇中的不同步驟讀取不一致數據時,因為讀取之間會發生更新。

解決數據異常的策略

若要減少或防止這些異常狀況,請考慮下列對策:

  • 語意鎖定:使用應用層級鎖定,其中saga的可補償交易會使用旗號來指出更新正在進行中。

  • 通勤更新:設計更新,使其可以依任何順序套用,同時仍產生相同的結果,減少傳奇故事之間的衝突。

  • 悲觀檢視:重新排序傳奇的序列,讓數據更新在可重試的交易中發生,以消除骯髒的讀取。 否則,一個傳奇可以讀取髒數據(未認可的變更),而另一個傳奇同時執行可補償的交易來回復其更新。

  • 重新讀取值:驗證數據在進行更新之前仍維持不變。 如果數據變更,請中止目前的步驟,並視需要重新啟動傳奇。

  • 版本檔案:維護記錄上所有作業的記錄檔,並確保它們是以正確的順序執行,以避免衝突。

  • 風險型並行存取:根據潛在商務風險動態選擇適當的並行機制。 例如,針對高風險更新使用sagas,並針對高風險的更新使用分散式交易。

使用此模式的時機

當您需要下列專案時,請使用 Saga 模式:

  • 確保分散式系統中的數據一致性,而不需要緊密結合。
  • 復原或補償序列中的其中一個作業失敗。

Saga 模式不適合:

  • 緊密結合的交易。
  • 補償先前參與者中發生的交易。
  • 迴圈相依性。

後續步驟

  • 分散式數據
  • 理查森,克裡斯 2018:微服務模式。 曼寧出版物。

實作此模式時,下列模式可能也很有用:

  • 編舞 讓系統的每個元件都參與商務交易工作流程的決策程式,而不是依賴控制中心點。
  • 補償交易 一系列步驟執行的復原工作,並在一或多個步驟失敗時,最終定義一致的作業。 實作複雜商務程式和工作流程的雲端裝載應用程式通常會遵循此 最終一致性模型
  • 重試 可讓應用程式在嘗試連線到服務或網路資源時處理暫時性失敗,方法是以透明方式重試失敗的作業。 重試可以改善應用程式的穩定性。
  • 斷路器 處理在連線到遠端服務或資源時,需要一段時間才能復原的錯誤。 斷路器可以改善應用程式的穩定性和復原能力。
  • 健康情況端點監視 實作應用程式中的功能檢查,外部工具可以定期透過公開的端點進行存取。 健康情況端點監視可協助驗證應用程式和服務是否正常執行。