分布式事务方案:二阶段提交
分布式事务方案:
二阶段提交
TCC协议
异步确保型
事务型消息
以上四种广为人知的是分布式事务的一致性解决方案,其中只有二阶段提交是可以保证对应的CAP原理当中的强一致性和分区容忍性,其余的三种都是保证了可用性和分区容错性。
二阶段提交
二阶段提交的实现方式
假设对应的分布式事务场景如下:
【交易系统】就是transaction Manager(TM),【商品系统】和【优惠券系统】分别是Server1和Server2。
在二阶段提交协议当中,我们引入了一个【事务协调者】的概念,一般把它称作【事务管理者】。第一阶段TM会分别向两个服务发送prepare请求,两个服务会对应开启本地事务并执行,执行完毕会有ack回馈,告诉TM回滚的操作成功;TM需要收到两个服务的ack确认,才会向两个服务发起commit操作。只有这样才算完成事务。
鉴于二阶段提交是强一致性的,如果二阶段提交还没完成(还没commit),这个时候有Client来读取对应的服务,因为对应数据在prepare阶段是加了排它锁的,所以读取时就会阻塞住。只有commit之后才会释放perpare阶段的锁;亦或者服务还没commit就挂掉了,那服务重启之后就会去redo log回放prepare阶段的操作,然后锁死对应的数据,到TM反查当前事务是否需要重发commit,同样还没commit,对应的数据就没法被读取。
基于实现方式,【二阶段提交】的性能是比较差的,如果分布式参与者越多,意味着不可用的时间可能会更长,所以在互联网实际场景中比较少用。
有优化的空间吗?这就不得不提到一个中间件Zookeeper,它是分布式的,在数据同步这块也是分布式事务。整个集群会有一个Leader跟多个Follower,它数据同步是通过【二阶段提交】外加【Raft同步】(要求超过一半以上的节点同步成功即可算写成功)实现的。
既然只需要一半以上,那就会有Follower同步失败的可能,Zookeeper选举机制也是基于Raft,超过一半的节点认为你的数据是最新的,那么你就有资格成为Leader(具体的选举细节不止这么简单,详情了解下面的资料),选出Leader之后会进行数据同步,把Leader最新的数据和日志同步到Follower中,当半数以上的Follower同步数据成功后Leader才能成为真正的Leader,就可以处理事务请求了,之前同步失败的Follower也能同步回来。
ZooKeeper 的 Leader 选举 + ZooKeeper 集群的数据同步