ACID 過時?用 Sagas 搞定數據一致性
ACID Is So Yesterday: Maintaining Data Consistency with Sagas
Chris Richardson
Founder of Eventuate.io
Founder of the original CloudFoundry.com Author of POJOs in Action
本文素材作者 Chris Richardson,由坐館老 G 先生註解
講義 goal:
分佈式數據管理在微服務架構下的挑戰
Sagas 是一種事務模型
關於作者 Chris
大大有名
POJO‘s in action
Microservice Patterns
微服務 enable 持續部署
架構、組織和過程三角
**架構:**微服務架構
**組織:**小、敏捷、自組織功能團隊
**過程:**持續交付 / 部署
services = testability and deployability
松耦合,數據封裝
如何維護數據一致性呢?
由於不在一個(本地)事務中......
2PC 不是一個好的選擇
//
1、2PC 事務協調器單點故障問題
2、通訊:至少有 O(4n)條消息,並重試 O(n^2)
3、鎖導致吞吐量降低
4、許多 NoSQL 數據庫(或消息代理)不支持
5、CAP 理論 ⇒ 2PC 影響可用性
Ebay 的 Dan Pritchett 提出:
In partitioned databases, trading some consistency for availability can lead to dramatic improvements in scalability.
並有一個著名的 Base 理論。
Basically Available
Soft state
Eventually consistent
sagas 可以追溯到 1987 年的論文
1987 年普林斯頓大學的 Hector Garcia-Molina 和 Kenneth Salem 發表了一篇 Paper Sagas,講述的是如何處理 long lived transaction(長活事務)。Saga 是一個長活事務可被分解成可以交錯運行的子事務集合。其中每個子事務都是一個保持數據庫一致性的真實事務。
Saga 的組成
-
每個 Saga 由一系列 sub-transaction Ti 組成
-
每個 Ti 都有對應的補償動作 Ci,補償動作用於撤銷 Ti 造成的結果
可以看到,和 TCC 相比,Saga 沒有 “預留” 動作,它的 Ti 就是直接提交到庫。
Saga 的執行順序有兩種:
-
T1, T2, T3, ..., Tn
-
T1, T2, ..., Tj, Cj,..., C2, C1,其中 0 < j < n
Saga 定義了兩種恢復策略:
-
backward recovery,向後恢復,補償所有已完成的事務,如果任一子事務失敗。即上面提到的第二種執行順序,其中 j 是發生錯誤的 sub-transaction,這種做法的效果是撤銷掉之前所有成功的 sub-transation,使得整個 Saga 的執行結果撤銷。
-
forward recovery,向前恢復,重試失敗的事務,假設每個子事務最終都會成功。適用於必須要成功的場景,執行順序是類似於這樣的:T1, T2, ..., Tj(失敗), Tj(重試),..., Tn,其中 j 是發生錯誤的 sub-transaction。該情況下不需要 Ci。
Sagas complicate API design (Sagas 使 API 設計 複雜化 )
Synchronous API vs Asynchronous Saga
Request initiates the saga. When to send back the response?
Option #1: Send response when saga completes:
- Response specifies the outcome - Reduced availability
選擇一:saga 完成的時候發送響應
Option #2: Send response immediately after creating the saga
(recommended)
選擇二:創建 saga 之後馬上發送響應(推薦)
- Improved availability(提高可用性)
- Response does not specify the outcome. Client must poll or be notified
(響應沒有指定結果。必須輪詢或通知 Client 端)
使用 Sagas,可能影響用戶體驗。
UI 界面向用戶隱藏異步 API
如果需要更長的時間, 用戶界面顯示 “處理中” 彈出窗口
服務器可以將通知推送到 UI
Sagas 擁有 ACD 特性
原子性、一致性、持久性
缺失隔離性
Commutative updates
e.g. debit account can compensate for a credit account
Version file (版本文件)
Record history of changes (記錄變化歷史)
Use them to make updates commutative
e.g. record cancel reservation(記錄 取消 預定) so that create/cancel = cancel/ create
Sounds suspiciously like event sourcing
Choreography (編排): distributed decision making vs.
Orchestration(協調): centralized decision making
方案 1: 使用事件做基於編排模式的協作
優缺點:
Benefits (好處)
簡單,尤其使用事件溯源時
參與者松耦合
Drawbacks (缺點)
循環依賴
領域對象過載,例如訂單和客戶相互知道太多
Events = ndirect way to make something happen to make something happen
選項 2:基於編排的 saga 協調
saga(orchestrator ) 是一個持久性對象,跟蹤 saga 的狀態,以及調用參與者
這裏有一個例子,開源的 saga 框架
優缺點
Benefits
Centralized coordination logic is easier to understand
Reduced coupling, e.g. Customer knows less
Reduces cyclic dependencies
Drawbacks
Risk of smart sagas directing dumb services
消息必須支持事務
選擇 1: 使用數據庫表作爲消息隊列,ebay 的案例
選擇 2: 使用事件溯源:以事件爲中心的持久化
**技術瑣話 **
以分佈式設計、架構、體系思想爲基礎,兼論研發相關的點點滴滴,不限於代碼、質量體系和研發管理。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/inmU2c6O6bIe5wGq-lT_bQ