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 T i 组成

  • 每个T i 都有对应的补偿动作C i ,补偿动作用于撤销T i 造成的结果

可以看到,和TCC相比,Saga没有“预留”动作,它的T i 就是直接提交到库。

Saga的执行顺序有两种:

  • T 1 , T 2 , T 3 , ..., T n

  • T 1 , T 2 , ..., T j , C j ,..., C 2 , C 1 ,其中0 < j < n

Saga定义了两种恢复策略:

  • backward recovery,向后恢复,补偿所有已完成的事务,如果任一子事务失败。即上面提到的第二种执行顺序,其中j是发生错误的sub-transaction,这种做法的效果是撤销掉之前所有成功的sub-transation,使得整个Saga的执行结果撤销。

  • forward recovery,向前恢复,重试失败的事务,假设每个子事务最终都会成功。适用于必须要成功的场景,执行顺序是类似于这样的:T 1 , T 2 , ..., T j (失败), T j (重试),..., T n ,其中j是发生错误的sub-transaction。该情况下不需要C i 。

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: 使用事件溯源:以事件为中心的持久化