常见分布式事务解决方案

2019-09-26  本文已影响0人  伊凡的一天

1. CAP定理

CAP定理表示一个分布式web服务至多只能支持下面三项中的两项:

事实上,这儿的三选二实际上是只在满足分区容错性的前提下,一致性和可用性必须二选一。如果集群一部分机器失联,此时来了一个写请求到主机A,如果为了保证一致性,那么A就必须阻塞这个写请求知道集群网络恢复;如果为了保证可用性,那么A就必须接受这个写请求,这样集群中数据一致性就遭到了破坏。

2. 2PC

2PC(2 phase commit)是最早的分布式事务解决方案,它在集群中引入了两个角色:Coordinator和Participants,即协调者和参与者。它的两阶段提交分为Vote阶段和Commit阶段,具体过程如下:

1. 第一阶段(Vote阶段):Coordinator向事务的多个参与者发送prepare消息,参与者收到详细后要么直接返回失败,要么在本地写入redo和undo日志,然后执行事务,但并不提交。

2. 第二阶段(Commit阶段):Coordinator收到各个事务参与者的消息后,如果所有的参与者返回的都是agreement时,Coordinator发送commit消息给各个事务参与者进行事务提交;否则,Coordinator发送rollback消息给事务参与者进行事务回滚。

2PC是一个阻塞协议,如果事务的Coordinator永久宕机,事务的一部分参与者将永远无法完成事务,它们会一直等待Coordinator发送 COMMIT 或者 ROLLBACK 消息。另外如果仅仅部分参与者收到了Commit消息,就会出现多个参与者数据状态不一致的问题。

3. 3PC

针对2PC存在的一些问题,3PC种增加了准备阶段和超时机制。也就是说,3PC把2PC的投票阶段再次一分为二,这样3PC提交就有CanCommitPreCommitDoCommit三个阶段。

为什么要把投票阶段一分为二?
假设有1个协调者,9个参与者。其中有一个参与者不具备执行该事务的能力。
协调者发出prepare消息之后,其余参与者都将资源锁住,执行事务,写入undo和redo日志。
协调者收到相应之后,发现有一个参与者不能参与。所以,又出一个roolback消息。其余8个参与者,又对消息进行回滚。这样子,是不是做了很多无用功?
所以,引入can-Commit阶段,主要是为了在预执行之前,保证所有参与者都具备可执行条件,从而减少资源浪费。

相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态。

但是3PC也会存在着数据一致性问题。例如,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。

超时后执行commit动作其实是基于概率来决定的,当进入第三阶段时,说明参与者在第二阶段已经收到了PreCommit请求,那么协调者产生PreCommit请求的前提条件是他在第二阶段开始之前,收到所有参与者的CanCommit响应都是Yes,因此他有理由相信commit的几率很大。

4. TCC(补偿事务)

TCC可以看作业务级别的2PC。TCC对应着Try,Confirm和Cancel。它要求所有的服务都对外提供这三个接口。Try,Confirm和Cancel的含义如下:

1. Try:对业务系统做检测及资源预留
2. Confirm:真正的执行具体的业务操作
3. Cancel:释放Try阶段预留的业务资源

下面是TCC的模型图:


TCC.jpg

从业务服务必须实现Try、Confirm和Cancel三个接口,供主业务服务调用。由于Confirm和Cancel操作可能被重复调用,故要求Confirm和Cancel两个接口必须是幂等的。

TCC事务的优点如下:

TCC事务的缺点在于TCC的Try、Confirm和Cancel操作功能需业务提供,开发成本高(业务能否提供一个健壮的TCC接口是一个问题)。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。

5. 消息队列实现的最终一致性

消息队列实现最终一致性.PNG

6. seta分布式事务框架原理

参考文章

上一篇 下一篇

猜你喜欢

热点阅读