sysDesign-分布式事务

栏目: 后端 · 发布时间: 4年前

分布式事务-掘金 分布式事务的解决方案有很多种, 一致性从强到弱,性能开销从从多到少:三阶段,二阶段,TCC,saga 一致性保障的基本思路,协调者掌握多个子流程的执行过程信息,协调者负责根据子流程执行信息作出决策

分布式事务产生的原因

  • 不同的service节点
    • 一个事务流程需要调用不同的服务执行不同的子任务
  • 不同的resource节点
    • 一个事务会调用不同的数据来源,例如 mysql 的分库操作

分布式事务的原则

CAP原则

  • CAP的解释
    • C 一致性原则,此处值得是读取到的数据都是事务完成之后和事务完成之前的数据,对于数据事务的中间状态时不可见的
    • A 可用性,非故障节点在合理的合理的时间内返回合理的响应
    • P 分区容错性,当出现网络分区后,仍能继续工作。例如某个节点故障了之后,集群仍能继续工作
  • 对于CAP原则,P是大前提,因此CAP解释成,当P发生时,A和C只能选一个 ,假设节点1和节点2正好处于网络分区的两侧,例如节点1网络正常,而节点2网络故障。这时,一个事务请求到达集群,节点2一定是不能正常处理的,节点1对于该事务请求
    • 如果节点1也对该事务不执行,这保证了C,但是违背了A
    • 如果节点1对该事务执行,这保证了A,但是违背了C

BASE原则

  • BASE指的是,基本可用,软状态和最终一致性,是对AP的一种扩展
  • BASE允许存在中间状态,牺牲了一致性而保证了可用性,但是必须是强一致的状态

解决方案

2PC 两阶段提交协议

  • 存在一个协调者,多个参与者
  • 步骤:
    • 第一阶段:
      • 协调者想参与者发出投票,等待各个参与者的响应
      • 各个参与者执行事务,并写入redo log和undo log(此时资源还未释放)
      • 参与者响应协调者发起的投票,若事务执行成功,则响应同意,若执行失败,则响应终止
    • 第二阶段
      • 当所有的参与者都同意时,
        • 协调者向参与者发送正式提交的请求
        • 参与者收到后,完成事务的提交,并释放占用的资源
        • 向协调者发送完成响应
        • 协调者收到所有完成响应后,完成事务
      • 当存在终止响应时,
        • 协调者向参与者发出回滚请求
        • 参与者利用undo log将事务回滚,并释放资源
        • 参与者向协调者发送回滚完成
        • 协调者等待所有的回滚完成后,结束事务
  • 会存在很多的问题
    • 所有参与者对资源的占用都是阻塞的
    • 协调者要对参与者设定超时机制
    • 太依赖协调者,一旦宕机,会导致整个事务阻塞

3PC 三阶段提交协议

  • 引入超时机制,同时将准备阶段一分为二
  • 步骤
    • canCommit
      • 协调者向参与者发送canCommit请求,并等待响应
      • 参与者接收到请求后,如果认为自己可以执行,则返回YES,否则NO
    • preCommit
      • 如果参与者响应都是YES
        • 向参与者发送preCommit请求
        • 参与者进行事务的执行,并进行redo log,undo log的落地
        • 如果成功执行了指令,则返回ack响应,同时开始等待最终指令
      • 如果存在一个NO,或者存在超时
        • 向参与者发送中断请求
        • 参与者接收到了abort请求之后,或则超时未收到协调者的请求,会将事务中断
    • doCommit
      • 若接收到了所有参与者的ack之后,
        • 向所有的参与者发送doCommit请求
        • 参与者接收到了请求后,执行事务并释放资源,发送ack给协调者
        • 协调者接收到所有的ack之后,完成事务
      • 若未收到所有的ack或者存在超时响应
        • 向所有的参与者发送abort请求
        • 参与者收到后根据之前的undo log进行回滚操作,并释放所有资源
        • 想协调者发送ack响应
        • 协调者收到ack后,终止事务

TCC模型 (两阶段型,补偿型)

  • TCC为Try Confirm Cancel
    • Try尝试待执行的业务
      • 并未执行业务,只进行一致性检查,但是预留资源
    • Confirm执行业务
      • 直接执行,使用第一步预留的资源
    • Cancel取消执行的业务
      • 如果业务失败,则进行资源的回滚,释放占用资源
  • TCC必须基于本地事务
  • 必须提供幂等性保障
    • 会存在一些超时重试补偿机制

saga模型

  • 每个Saga由一系列sub-transaction Ti 组成
  • 每个Ti 都有对应的补偿动作Ci,补偿动作用于撤销Ti造成的结果,这里的每个T,都是一个本地事务。
  • 可以看到,和TCC相比,Saga没有“预留 try”动作,它的Ti就是直接提交到库。
  • Saga的执行顺序有两种:
    • T1, T2, T3, …, Tn
    • T1, T2, …, Tj, Cj,…, C2, C1,其中0 < j < n
  • Saga定义了两种恢复策略:
    • 向后恢复,即上面提到的第二种执行顺序,其中j是发生错误的sub-transaction,这种做法的效果是撤销掉之前所有成功的sub-transation,使得整个Saga的执行结果撤销。
    • 向前恢复,适用于必须要成功的场景,执行顺序是类似于这样的:T1, T2, …, Tj(失败), Tj(重试),…, Tn,其中j是发生错误的sub-transaction。该情况下不需要Ci。
  • 这里要注意的是,在saga模式中不能保证隔离性,因为没有锁住资源,其他事务依然可以覆盖或者影响当前事务。

    还是拿100元买一瓶水的例子来说,这里定义 T1=扣100元 T2=给用户加一瓶水 T3=减库存一瓶水 C1=加100元 C2=给用户减一瓶水 C3=给库存加一瓶水 我们一次进行T1,T2,T3如果发生问题,就执行发生问题的C操作的反向。 上面说到的隔离性的问题会出现在,如果执行到T3这个时候需要执行回滚,但是这个用户已经把水喝了(另外一个事务),回滚的时候就会发现,无法给用户减一瓶水了。这就是事务之间没有隔离性的问题

  • 可以看见saga模式没有隔离性的影响还是较大,可以参照华为的解决方案:从业务层面入手加入一 Session 以及锁的机制来保证能够串行化操作资源。也可以在业务层面通过预先冻结资金的方式隔离这部分资源, 最后在业务操作的过程中可以通过及时读取当前状态的方式获取到最新的更新。

以上所述就是小编给大家介绍的《sysDesign-分布式事务》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Mechanics of Web Handling

The Mechanics of Web Handling

David R. Roisum

This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具