微服務架構分散式事務管理問題

banq發表於2022-08-14

分散式事務管理問題:如何處理跨多個服務的事務?

微服務架構分散式事務管理問題
微服務是一個分散式系統。一個事務被分發給多個服務,這些服務被順序或並行呼叫以完成整個事務。對於微服務架構,最常見的模式是每個微服務的資料庫,因此事務也需要跨越不同的資料庫。
隨著微服務架構的出現,分散式事務管理存在兩個關鍵問題:
子問題

  • 如何維護事務的原子性。原子性意味著事務中的所有步驟都必須成功,或者如果某個步驟失敗,則應該回滾之前完成的所有步驟。然而,在微服務架構中,一個事務可以由不同微服務處理的多個本地事務組成。因此,如果本地事務之一失敗,如何回滾之前完成的成功事務?
  • 如何管理併發請求的事務隔離級別。事務隔離級別指定事務中的語句可見的資料量,特別是當多個服務呼叫同時訪問同一個資料來源時。如果來自任何一個微服務的物件被持久化在資料庫中,而另一個請求同時讀取同一個物件,服務應該返回舊資料還是新資料?


如何解決這個問題?
在設計基於微服務的應用程式時解決這兩個問題至關重要。以下是解決這些問題的兩種方法:

  1. 兩階段提交 (2PC)
  2. Saga


兩階段提交 (2PC)
兩階段提交是資料庫系統中眾所周知的模式。這種模式也可以用於微服務來實現分散式事務。在兩階段提交中,有一個控制節點包含執行操作的大部分邏輯和參與節點(微服務)。它分兩個階段工作:

  • 準備階段(階段 1):控制節點詢問所有參與節點是否準備好提交。參與節點以是或否響應。
  • 提交階段(階段 2):如果所有節點的回答都是肯定的,則控制節點要求它們提交。即使一個節點的回答是否定的,控制節點也會要求它們回滾。


微服務架構分散式事務管理問題

儘管 2PC 可以幫助在分散式系統中提供事務管理,但它也成為單點故障,因為事務的責任落在了協調者身上。隨著階段的數量,整體效能也會受到影響。由於協調器的健談,整個系統受到最慢資源的約束,因為任何就緒節點都必須等待來自較慢節點的確認。此外,這種協調器的典型實現本質上是同步的,這可能導致未來吞吐量降低。2PC還是有以下缺點:

  • 如果一個微服務在提交階段變得不可用,則沒有機制可以回滾另一個事務。
  • 其他服務必須等到最慢的服務完成確認。服務使用的資源被鎖定,直到整個事務完成。
  • 由於它們依賴於事務協調器,兩階段提交在設計上很慢。這可能會導致可伸縮性問題,尤其是在基於微服務的應用程式和涉及許多服務的回滾場景中。


Saga
正如 Hector Garcia-Molina 和 Kenneth Salem 在其 1987 年計算機協會文章中所描述的那樣,Saga是執行特定工作單元的一系列操作,並且通常相互交錯。作為 Saga 一部分的每個操作都可以透過補償操作回滾。Saga 保證所有操作成功完成,或者為所有執行的操作執行相應的補償操作以回滾之前完成的任何工作。

補償動作必須是冪等的,並且必須能夠重試直到成功執行,本質上使它成為一個不會失敗的動作,並且不需要人工干預來解決它的失敗。Saga 執行協調器 (SEC) 為整個流程提供了保證和能力,使其成為成功或成功中止並具有必要回滾的事務。
Saga 模式在分散式事務場景中有何幫助?

微服務引入了另一組管理事務的問題,因為每個域驅動的服務都是單獨部署並隔離執行的。使用微服務架構,單個業務流程將多個微服務組合在一起以提供整體解決方案。使用微服務架構實現 ACID(原子性、一致性、隔離性、永續性)事務非常困難,並且在某些情況下是不可能的。例如,在上述電子商務示例中,具有優惠券功能的微服務無法獲取支付資料庫的鎖定,因為它在大多數情況下是外部服務。但是仍然需要某種形式的事務管理,所以這些事務被稱為BASE事務:基本可用性、軟狀態和最終一致性。必須採取補償措施來恢復作為交易的一部分發生的任何事情。

這是 Saga 模式完美契合的地方,因為它有助於:

  • 跨多個微服務保持數​​據一致性,無需緊密耦合。
  • 與 2PC 相比,效能更好。
  • 不提供單點故障。
  • 保持事務的整體狀態最終一致


實現 Saga 模式的不同方法
實現 Saga 模式有兩種合乎邏輯的方式:編舞Choreography和編排orchestration。

編舞Choreography
在 Saga 編舞模式中,作為流程一部分的每個單獨的微服務都會釋出一個事件,該事件由後續的微服務接收。您必須在微服務開發生命週期的早期做出決定,以瞭解它是否會成為 Saga 模式的一部分,因為您必須選擇一個合適的框架來幫助實現該模式。要採用特定的框架程式碼,必須使用註釋、類初始化或其他配置更改來裝飾微服務。在 Saga 編舞模式中,SEC 可以嵌入到微服務中,或者在大多數場景中是一個獨立的元件

微服務架構分散式事務管理問題


每當服務出現時,它都會向 SEC 註冊,這使其成為可能跨越各種微服務的交易的一部分。SEC 在其日誌中維護事件的順序,這有助於它決定在發生故障時呼叫的補償服務和順序。

當參與分散式事務的微服務數量在 2 到 4 個之間時,首選編舞實現。在超過 4 個服務的情況下,應用編排實現更合適。
Saga 編舞模式是您開始微服務之旅(本質上是全新開發)並瞭解有必要適時引入流程微服務的理想選擇。
編舞的缺點

  • 很難跟蹤哪個服務正在偵聽哪個佇列。新增新服務可能既困難又令人困惑。
  • 服務之間存在迴圈依賴的風險,因為它們會消耗彼此的佇列。
  • 整合測試很困難,因為必須執行所有服務才能模擬流程。


編排orchestration
正如 Saga 編排模式的名稱所暗示的那樣,有一個編排器元件負責管理整個流程。如果程式在呼叫任何單個微服務時遇到錯誤,那麼它也負責呼叫補償服務。編排器幫助對 Saga 流進行建模,但也依賴底層框架按順序呼叫服務,並在任何服務失敗時進行補償呼叫。

微服務架構分散式事務管理問題


編排的優勢

  • 它非常適合存在許多服務並且隨著時間的推移新增服務的複雜工作流程。這裡,下限是 4 個服務。如果服務超過 4 個,則優先使用編排實現
  • 它提供對每個服務及其活動的集中控制。
  • 由於編排實現單方面依賴於 Saga 參與者(服務),因此不存在迴圈依賴。
  • 並非每個服務都需要了解其他服務的任何資訊!因此,存在關注點分離。
  • 它比編舞實現更容易實現和測試。
  • 由於完成的工作將保持線性,撤消或補償管理更容易。

編排實現的唯一缺點是整個工作流程由 Saga Orchestrator 管理(單點風險)。
因此
  • 可以看出,無論在 Saga 中使用哪種實現,無論是編排還是編排,複雜性都會隨著服務數量的增加而增加。
  • 在 Saga 中進行除錯是一項相當困難的操作。
  • 在 Saga 服務的本地資料庫中所做的任何更改都無法撤消!
  • 如果一個 Saga 處理資料而不讀取另一個 Saga 所做的更改,則可能會發生丟失更新。
  • 或者,當一個服務在完成更新之前讀取另一個服務所做的更新時,可能會發生髒讀。

由此產生的分散式事務問題得到了解決,但它的實現必須小心。

可以檢視開源示例 saga 專案

相關文章