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理论。
Base: An Acid Alternative
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: 使用事件溯源:以事件为中心的持久化
加入技术琐话粉丝群,公众号回复:技术群。
下载“100页ppt讲清楚云原生 ” ppt,公众号回复:高磊。
下载本ppt,公众号回复:sagas。
往期推荐:
技术琐话
以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理。