分布式事务简介
发布日期:2021-06-29 11:22:48 浏览次数:2 分类:技术文章

本文共 3341 字,大约阅读时间需要 11 分钟。

分布式事务简介


事务

BASE理论

BASE 理论是 Basically Available(基本可用),Soft State(软状态)和Eventually Consistent(最终一致性)三个短语的缩写。

  1. 基本可用(Basically Available):指分布式系统在出现不可预知故障的时候,允许损失部分可用性。
  2. 软状态(Soft State):指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
  3. 最终一致(Eventual Consistency):强调的是所有的数据更新操作,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

其核心思想是:

即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)

2PC

两阶段提交又称2PC,2PC是一个非常经典的强一致、中心化的原子提交协议。这里所说的中心化是指协议中有两类节点:一个是中心化协调者节点(coordinator)和N个参与者节点(partcipant)。

分为投票阶段提交/执行阶段。举例 订单服务A,需要调用 支付服务B 去支付,支付成功则处理购物订单为待发货状态,否则就需要将购物订单处理为失败状态。

第一阶段:投票阶段

  1. 事务询问协调者 向所有的 参与者 发送事务预处理请求,称之为Prepare,并开始等待各 参与者 的响应。
  2. 执行本地事务各个 参与者 节点执行本地事务操作,但在执行完成后并不会真正提交数据库本地事务,而是先向 协调者 报告说:“我这边可以处理了/我这边不能处理”。
  3. 各参与者向协调者反馈事务询问的响应如果 参与者 成功执行了事务操作,那么就反馈给协调者 Yes 响应,表示事务可以执行,如果没有 参与者 成功执行事务,那么就反馈给协调者 No 响应,表示事务不可以执行。第一阶段执行完后,会有两种可能。
    1. 所有都返回Yes。
    2. 有一个或者多个返回No。–> 失败,不进行第二阶段

第二阶段:提交/执行阶段(成功流程)

  1. 所有的参与者反馈给协调者的信息都是Yes,那么就会执行事务提交。协调者向所有参与者节点发出Commit请求.
  2. 事务提交:参与者收到Commit请求之后,就会正式执行本地事务Commit操作,并在完成提交之后释放整个事务执行期间占用的事务资源。

第二阶段失败回滚流程

  1. 发送回滚请求:协调者向所有参与者节点发出 RoollBack 请求.
  2. 事务回滚:参与者接收到RoollBack请求后,会回滚本地事务。

2pc可能出现的三种问题

作者:欧阳丰 链接:https://zhuanlan.zhihu.com/p/91263461 来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  1. 协调者正常,参与者宕机​:由于 协调者 无法收集到所有 参与者 的反馈,会陷入阻塞情况。​

    1. 解决方案:引入超时机制,如果协调者在超过指定的时间还没有收到参与者的反馈,事务就失败,向所有节点发送终止事务请求。
  2. 协调者宕机,参与者正常​:无论处于哪个阶段,由于协调者宕机,无法发送提交请求,所有处于执行了操作但是未提交状态的参与者都会陷入阻塞情况.​

    1. 解决方案:引入协调者备份,同时协调者需记录操作日志.当检测到协调者宕机一段时间后,协调者备份取代协调者,并读取操作日志,向所有参与者询问状态。
  3. 协调者和参与者都宕机

    1. 发生在第一阶段: 因为第一阶段,所有参与者都没有真正执行commit,所以只需重新在剩余的参与者中重新选出一个协调者,新的协调者在重新执行第一阶段和第二阶段就可以了。
    2. 发生在第二阶段 并且 挂了的参与者在挂掉之前没有收到协调者的指令。也就是上面的第4步挂了,这是可能协调者还没有发送第4步就挂了。这种情形下,新的协调者重新执行第一阶段和第二阶段操作。
    3. 发生在第二阶段 并且 有部分参与者已经执行完commit操作。就好比这里订单服务A和支付服务B都收到协调者 发送的commit信息,开始真正执行本地事务commit,但突发情况,Acommit成功,B确挂了。这个时候目前来讲数据是不一致的。虽然这个时候可以再通过手段让他和协调者通信,再想办法把数据搞成一致的,但是,这段时间内他的数据状态已经是不一致的了!
      2PC 无法解决这个问题。

3PC

三阶段提交协议(3PC)主要是为了解决两阶段提交协议的阻塞问题,2pc存在的问题是当协作者崩溃时,参与者不能做出最后的选择。因此参与者可能在协作者恢复之前保持阻塞。三阶段提交(Three-phase commit),是二阶段提交(2PC)的改进版本。

除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommitPreCommitDoCommit三个阶段。

抛开三阶段提交糟糕的性能(并且其也没有解决2pc丢数据的问题),超时也不是一种可靠的故障检测机制,因为即使没有节点崩溃,请求也可能由于网络问题而超时。出于这个原因,两阶段提交仍然被广泛使用,尽管存在协调者失效的问题。

所以,因为特性需要(一致性),分布式事务最终会走向分布式共识。

TCC

TCC (Try、Commit、Cancel) 是一种补偿型事务,该模型要求应用的每个服务提供 try、confirm、cancel 三个接口,它的核心思想是通过对资源的预留(提供中间态),尽早释放对资源的加锁,如果事务可以提交,则完成对预留资源的确认,如果事务要回滚,则释放预留的资源。

TCC 也是一种两阶段提交协议,可以看作 2PC/XA 的一种变种,但是不会长时间持有资源锁。

TCC 模型将事务的提交划分为两个阶段:

  1. 阶段 1
    • 完成业务检查(一致性)、预留业务资源(准隔离性),即 TCC 中的 try。
  2. 阶段 2
    • 如果 try 阶段所有业务资源都预留成功,则执行 confirm 操作,否则执行 cancel 操作:
      • confirm:不做任何业务检查,仅仅使用预留的资源执行业务操作,如果失败会一直重试。
      • cancel:取消执行业务操作,释放预留的资源,如果失败会一直重试。

TCC 模式中,事务的发起者参与者都需要记录事务日志,事务的发起者需要记录全局事务和各个分支事务的状态和信息;事务的参与者需要记录分支事务的状态。

TCC 事务在执行过程中的任意环节,均可能发生宕机、重启、网络中断等异常情况,此时事务处于非原子状态和非最终一致状态,此时就需要根据主事务记录和分支事务记录的日志,去完成剩余分支事务的提交或者回滚,使整个分布式事务内所有参展达到最终一致的状态,实现事务的原子性。

悲观锁与乐观锁

锁的一种宏观分类方式是悲观锁和乐观锁。悲观锁与乐观锁并不是特指某个锁(Java中没有哪个Lock实现类就叫PessimisticLock或OptimisticLock),而是在并发情况下的两种不同策略。

  • 悲观锁(Pessimistic Lock), 就是很悲观,每次去拿数据的时候都认为别人会修改。所以每次在拿数据的时候都会上锁。这样别人想拿数据就被挡住,直到悲观锁被释放。
  • 乐观锁(Optimistic Lock), 就是很乐观,每次去拿数据的时候都认为别人不会修改。所以不会上锁,不会上锁!但是如果想要更新数据,则会在更新前检查在读取至更新这段时间别人有没有修改过这个数据。如果修改过,则重新读取,再次尝试更新,循环上述步骤直到更新成功(当然也允许更新失败的线程放弃操作)。

悲观锁阻塞事务乐观锁回滚重试,它们各有优缺点,不要认为一种一定好于另一种。像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

参考链接

  1. 阿里技术的文章

转载地址:https://blog.csdn.net/zxpoiu/article/details/115740303 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:linux 丢包排查思路简述(tcp+rdma)
下一篇:Windows Azure Storage论文解读

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月22日 11时48分05秒