发布者:上海IT外包来源:http://www.lanmon.net点击数:1249
蓝盟IT小贴士,来喽!
分布式CAP理论应该是众所周知的,它描述了一致性(c )、可用性) a )、分区容错) p )的一系列折衷。 在许多情况下,我们必须在一致性和可用性之间做出权衡,但分布式事务就是在这个大前提下,尽可能达到一致性的要求。
目标小,问题大,做法也各不相同。
“如何在微服务中实现分布式事务处理? ”一般来说,当被问到这样的问题时,我会回答“尽量避免使用分布式事务处理”。 这也是Martin Fowler推荐的。 但是,现实总是残酷的,分割了微服务之后,分布式事务是非常硬的需求,无法绕开。 我们仍然必须想办法做那个。 但是,分散环境错综复杂,伴随着网络状况的超时,如何使事务处于一致的状态是很困难的。
分布式事务处理由一系列小的子事务处理组成。 这些子事务必须遵循ACID原则,就像大型分布式事务一样。 在一致性这一属性中,根据达到一致性之前存在的时间,可以分为强一致性和最终一致性(BASE )。
请注意,这里对子事务有一个小的误解。 并不是只有与数据库进行交互的操作才称为事务。 在微服务环境中,如果通过RPC调用另一个远程接口来改变相关数据的状态,则该RPC接口也称为事务。
因此,在分布式事务中,涉及这些子事务的操作称为资源。 操作成功完成时,不需要追加处理。 事务主要处理的是发生异常后的进程。
现在,让我们来看看常见的分布式事务解决方案。
1 .一级提交(1PC ) )。
首先,让我们来看看最简单的事务提交情况。
如果你的业务只有一个需要协调的资源,可以直接提交。 例如,如果使用的是数据库,则可以直接使用begin、commit等命令完成事务的提交。
在Spring中,通过注释可以完成这样的事务。 如果发生嵌套事务,其实现方法本质上通过ThreadLocal传递到下面。 所以,如果你的APP需要子线程相关的事务进行管理,那就不行了。
让我们来看看分布式事务。 分布式事务是指协调两个或多个资源以达到联合提交或联合失败的效果,即分布式ACID。
2 .分两个阶段提交(2PC ) )。
随着阶段提交概念的扩展,最简单的分布式事务处理解决方案是阶段提交。 阶段2提交不是指有两个参与资源,而是有两个分布式协调阶段,可能有多个需要协调的资源。2.1重要参与者
需要自制协调员,也就是事务经理。 整个系统通常只有一个
事务参与者(participants )是指我们所说的资源,通常有多个。 否则,就不能说是分布式事务
2.2工艺
广义的2PC(twophasecommit )有哪两个阶段呢?
客户端分布式事务启动者
提交-请求/提交准备阶段
提交/回滚提交或回滚
准备阶段也称为voting阶段。 voting是指参加者告知协调员,自己的资源是可以提交的(表示准备好了),还是取消这次的交易(例如发生异常的情况)。
这个投票很有趣,一个参与者返回false后,必须结束这个交易并执行rollback。 只有全票通过,才能正常被commit。 协调员知道这个结果,所有参加者的这个过程是两个阶段。
两阶段提交其实很容易理解。 每个参与者的执行可以被视为常规的SQL更新语句。 他们一直挂在那里,直到协调员发出准确的commit或rollback消息。
2.3问题
拦路问题。 两阶段提出的最大问题是它是被阻止的协议,效率低下。 如果协调员永久失败,一些参与者将无法完成事务
单点故障的问题。 由于协调员在整体中具有非常重要的作用,一旦发生SPOF,整个系统将无法使用,无法忍受
事务完整性问题。 在某些情况下,协调员发送commit命令后,可能会发生异常,导致某些执行成功,从而导致整个事务不一致。 因为能否提交,由第一阶段决定,所以第二阶段只有通知。 你死也要交出来
并非所有资源都支持2PC (或XA )
第三,举个例子。 例如,你的commit-request阶段全部返回yes,协调员发送了commit命令。 但是,此时,一个服务器a出现故障,无法执行此commit。 这个时候,我们的客户端也会收到成功的消息。 a重新启动机器后,需要恢复commit命令并继续执行的能力,这些必须在工程上处理。
2.4框架
2PC也称为XA事务,大多数数据库(如MySQL )支持XA协议。 在Java中,JTA (不是JPA哦) )是XA协议的实现。 Spring也有JTA的事务管理器。Atomikos、bitronix实现JTA,它们提供jar包即可。 实现了XA协议的数据库或消息队列具有各种准备、提交和回滚的能力
要使用seata之类的框架,必须启动独立的seata服务协调器节点。 seATa使用的at通过外部事务管理器,概念与XA相似
3 .三阶段提交(3PC ) )。
与两阶段提交相比,三阶段提交最典型的特征是加入了超时机制。 当然,三级证明它有三级,这种差异更为明显。 因为它本质上只是2PC的一些改善,所以身体里完全充满了2PC的影子。
3.1重要参与者
3PC和2PC是一样的。
3.2工艺
3PC比2PC增加了步长。 那个是咨询的阶段。
CanCommit查询阶段
提前提交准备阶段
do提交阶段
提交阶段只需要发送commit或rollback命令,重要的处理还在准备阶段,3PC将其分解为2。
请注意以下对应关系哦。 2PC和3PC有准备阶段,但它们的作用不同。
3PC 2PC
can commit commit -请求/建议
提前提交
o提交提交提交
3PC的咨询阶段,应对才是2PC的准备阶段,是ask参与者是否准备好了,但在执行过程上有一些差异。
为什么要这么做? 因为2PC有效率问题。 2PC的运行过程被阻止,一个资源进入准备阶段后,必须等待所有资源都准备好,然后再进行下一步。 在这个过程中,这些资源在全球一无所知。
例如,有ABCDE等5名参加者,但e实际上是有问题的参加者资源。 但是,2PC每次执行ABCD的预提交,在询问e时发现有问题,依次执行ABCD等参加者的rollback。 在这种情况下,ABCD执行了无用的事务预处理和回滚,非常浪费资源。
3PC通过划分这一呼叫阶段,在确保所有参与者健康的前提下,启动了真正的事务处理,在效率和承受能力方面表现出色。 从概率上来说,commit之前的粒度会变小,所以在commit阶段发生问题的概率会变低,可以节省很多事情。
另外,3PC引入了超时机制。 在PreCommit阶段,如果超时,将被视为失败; 在DoCommit阶段,即使超时也将继续执行。 无论如何,整个事务并不是一直在等待。3.3问题
3PC理论上很好,也可以避免阻塞问题,但增加了一次网络通信。 如果参加者数量多,网络质量差,这个开销就会非常大。 其实现也很复杂,在实用上并不多。
3PC也不完美。 由于PreCommit阶段和DoCommit也不是原子,所以它们与2PC相似,仍然存在一致性问题。
4 .电信
TCC是柔性事务,上面介绍的都是刚性事务。 在某些情况下,业务建模可以实现技术问题。
2PC和3PC在概念上看起来很简单,但如果放在分布式环境中考虑各种超时和停机问题,考虑周全,那真的会是旧命。
虽然2PC的框架还很多,但是3PC找遍了网络后,发现几乎没有有名的实现。
可悲的是,我们有更易懂、更直观的分布式事务。 那是TCC,2007年的古董。
TCC是一种知名的补偿事务,是互联网环境中最常用的分布式事务。 其核心思想是,针对每个操作,准备确认动作和相应的补偿动作三种方法。
与其依赖数据库,不如依赖自己的代码! 2PC,3PC,都被数据库绑死了。 TCC才是斯科农的最爱(也就是说要写很多代码)。
文/上海蓝盟 IT外包专家
分享到: