分布式事务

分布式事务

  1. 数据库事务
  • 原子性(Atomicity)
    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。原子性是一种业务述求,就是可能很多时候,很多业务是独立的,但是多个事情不可分割,要么都发生,要么不发生,也是常有的

  • 一致性(Consistency)
    事务前后数据的完整性必须保持一致。在原子性的述求下,保证数据一致性【对外的正确性】是最基本要求,既然有关联,就得有解决方案,方案就是想法子让一致

  • 隔离性(Isolation)
    事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。只要是多个事情就有中间状态,所谓强一致性就是,尽管我有中间状态,用redo,undo日志,事务开启,提交等,进行隔离,保证强一致性(其实所谓的最终一致性,就是没有隔离,看见了中间状态,包括一部分提交,一部分还没提交,也包括一部分提交,一部分失败了)

  • 持久性(Durability)
    持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。持久性是数据库的最基本功能,都不能保证持久化,还要数据干嘛

  1. 分布式事务
    2.1场景包括
  • 夸库
  • 分库分表
  • 夸应用

2.2 CAP理论
当单体应用或者数据库扛不住业务,分布式成为必然(或者说为了满足更大体量的业务要求,我们不得不分布式),显然单机ACID还是我们必须的,但是分布式又带来新的挑战可用性和分区容错性,这里为什么不变讨论AID呢原子性是一个业务述求,不要过多强调,如果没有原子性的业务述求,就不存在后续种种,隔离性其实和强一致性和若一致性性,包含在一致性里面了,BASE理论会提到,持久性数据库可以保证的,不会收到分布式的影响。简单讲:1. 原子性是一个基本业务述求,不会因为你分布式,业务述求就消失,2.持久性分布式后,数据库也能保证; 3. 一致性(包括隔离性)我们在分布式系统如何解决呢???

  • Consistency(一致性)本系统的客户端的一种承诺:要么我给您返回一个错误,要么我给你返回绝对一致的最新数据,不难看出,其强调的是数据正确。其实这个和数据库的一致性同理
  • Availability(可用性)任何客户端的请求都能得到响应数据,不会出现响应错误。换句话说,可用性是站在分布式系统的角度,对访问本系统的客户的另一种承诺:我一定会给您返回数据,不会给你返回错误,但不保证数据最新,强调的是不出错
  • Partition tolerance(分区容忍性)由于分布式系统通过网络进行通信,网络是不可靠的。当任意数量的消息丢失或延迟到达时,系统仍会继续提供服务,不会挂掉。换句话说,分区容忍性是站在分布式系统的角度,对访问本系统的客户端的再一种承诺:我会一直运行,不管我的内部出现何种数据同步问题,强调的是不挂掉。

CAP只能3选2,网上都说P必选,其实是一种误导。首先客户最基本述求是原子性(持久性是一个前提,磁盘硬件解决的,其实事务都是在持久性的前提下,围绕原子性的需求来讨论的,原子性的述求带来了一致性和隔离性的问题要解决),分布式以后,业务多出来一个述求可用性,应用多了,本来业务体量大了后就扛不住,分布式通信开销也成为了瓶颈。我理解分区容错性业务感知是不明显,因为99%的情况,系统通信都没啥问题,我们努力去解决AC问题就行特别注意,不是说放弃P,AC就自然满足了,我们也是需要去解决的,选了AC,无论如何也解决不了P的问题,如何解决呢,性能优化,没事就开启长事务,搞不好就超时了,数据库一致性还是要继续用起来的。1%的情况,系统通信故障(包括业务接口报错,或者不能扣钱等)我们可以放弃吗?显然在不行,在这个P的前提下,我们只能选择AP和CP,选择CP最简单,直接放弃了可用性,客户哪里能忍,一般我们选择AP但是C也不能彻底放弃,当P出现时候我们选择AP,暂时放弃C,但P很快会消失,消失后C难道也不管吗?显然不行

CP系统代表:zookeeper(leader宕机后,选举阶段,系统不可用)
AP系统代表:Eureka

我理解的XA(两阶段或三阶段提交),更偏向CP一些,基本还是靠长事务来解决的,只是做了些优化,最终也不能保证CP,局部选择了AP

2.3 BASE理论
AP虽然比CP复杂,但是用户体验更好,但是C对系统数据很重要,绝不可放弃,因此诞生了AP解决方案的BASE理论,BASE是CP(强一致性)和AP(强可用性)权衡的结果

  • Basically Available(基本可用)
    响应时间上的损失:正常情况下,处理用户请求需要0.5s返回结果,但是由于系统出现故障,处理用户请求的时间变成3s。并不是无脑处理,还是给C最终一致性,做些基础准备,尽量保证A,但是也做一些牺牲
    系统功能上的损失:正常情况下,用户可以使用系统的全部功能,但是由于系统访问量突然剧增,系统的非核心功能无法使用。优先保证可用,极限情况选择CP,因为无脑AP可能脏数据不是系统能吃得消的
  • Soft state(软状态)
    数据同步允许一定的延迟。放弃了强一致性
  • Eventually consistent(最终一致性)
    系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态,不要求实时。但是要求最终能一致

2.4 分布式事务解决方案

  • 基础理论Paxos算法,RATF算法
  • 2PC 全局锁,悲观锁,一把大锁全锁住
  • 3PC(XA)全局锁,悲观锁,一把大锁全锁住
  • TCC 分段锁,悲观锁,各自锁住,然后各自内部保证
  • SAGA 乐观锁,先按照能成功处理,成功不了再想办法兜底
  • TA(可以简单理解阿里实现的应用层的XA)

2.4.1 Paxos算法
假设:消息通信,消息不可靠,应用也不可靠
Paxos算法运行在允许宕机故障的异步系统中,不要求可靠的消息传递,可容忍消息丢失、延迟、乱序以及重复。它利用大多数 (Majority) 机制保证了2F+1的容错能力,即2F+1个节点的系统最多允许F个节点同时出现故障

https://zhuanlan.zhihu.com/p/31780743

  • 大家没聚在一起,只能通过消息通信(其实就是分布式),不会故意下达
  • 消息谁能保证及时送达(网络不能保证,送信的可能死掉了),但是可能重发,足够长时间一定送达
  • 正常情况大家不会拒绝(不会故意下达错误的指令,就是明明自己提交了,还说发没提交的信息),但是由于死掉了,或者暂时处理不了,或者条件不允许可能会拒绝

1、选择一个节点成为leader/proposer,必须有个leader(其实是Multi-Paxos),leader如何产生呢,可以用Basic-Paxos算法,就是分布式广播选举,比如大家先通信一波,确认各自的序号,然后大家都选最大的,然后大家都同意,结束,但是,网络故障,可能出现分区,A以为最大是3,B以为最大是5,

2、leader选择一个值,发送到所有的节点(Paxos中称之为acceptor),这个消息被称为“接受请求”消息。acceptor可以回应接受或拒绝。一次决议只解决一个问题

3、一旦节点中的大多数回应接受,共识就能达成,协调者将“提交”消息发送到所有节点,leader来统筹达成共识的问题,一旦达成共识,就群发,所有人都会尽力去做

  1. 获取一个Proposal ID n,为了保证Proposal ID唯一,可采用时间戳+Server ID生成;
  2. Proposer向所有Acceptors广播Prepare(n)请求;
  3. Acceptor比较n和minProposal,如果n>minProposal,minProposal=n,并且将 acceptedProposal 和 acceptedValue 返回;
  4. Proposer接收到过半数回复后,如果发现有acceptedValue返回,将所有回复中acceptedProposal最大的acceptedValue作为本次提案的value,否则可以任意决定本次提案的value;
  5. 到这里可以进入第二阶段,广播Accept (n,value) 到所有节点;
  6. Acceptor比较n和minProposal,如果n>=minProposal,则acceptedProposal=minProposal=n,acceptedValue=value,本地持久化后,返回;否则,返回minProposal。
  7. 提议者接收到过半数请求后,如果发现有返回值result >n,表示有更新的提议,跳转到1;否则value达成一致。

2.4.1 2PC全局锁
拆分了数据库事务的执行和提交(也可能是回滚)动作
两阶段提交:事务参与者,第一阶段只执行事务,但是不提交,执行完成告知事务协调者TC,TC收到所有事务参与者的准备完成后,给所有参与者发送提交commit指令,然后都开始提交。问题:阻塞、单点、以及第二阶段协调者挂了,数据不一致
![请添加图片描述](https://img-blog.csdnimg.cn/2beacc96d5934b99aa4f1a914e501038.jpeg
请添加图片描述

2.4.2 3PC全局锁
1. 校验要前置而不是一味兜底、2. 阻塞要搭配超时使用,当然超时也会引发新的问题,3PC并没有解决这些问题

三阶段提交是2PC的优化,前置检查一般就是检查资源是否具备,所是否能获取等等,而不是上来大家都直接执行。2PC比3PC简单,如果执行都没问题,那么第3阶段就是提交动作,没啥问题,如果是回滚动作,前面大叫都累死,结果要回滚,加入前置校验,可以很大程度避免第三阶段回滚,就是做一步前置检查,1是避免不必要的执行动作,2是校验后各执行者事务也会快(比如多半锁就可以立即获得),减轻了阻塞因为终究还是阻塞的形式,超时机制不可少,避免一直卡死,但是也带来了数据不一致的风险
请添加图片描述
2.4.2 TCC 悲观锁
2PC和3PC都是拆分了数据库的事务,也就是数据库使用长事务。TCC没有拆分数据库的事务执行和提交,是业务层面的拆分。1.资源预留与冻结,需要改造业务以及表结构;如果预留成功,就各自执行提交(就需要各自系统保证能处理完成了),否则就取消预留,解除冻结,(同样需要各自系统保证能取消掉)

好处:各系统的事务彻底隔离开了
缺点:1.改造成本大, 2. 各系统内部不管是执行提交,还是取消预留都要各自保证,3. 也是最终一致性
请添加图片描述
2.4.2 SAGA 乐观锁
TCC是直接改造原有逻辑,而SAGA是原有逻辑不变,作补偿
阶段一:当没有分布式问题(就是一般不会出问题,大胆点),各自分头执行
阶段二:有两条路子,路子1.依次回滚(回滚链路需要编排)路子2.往前恢复,直到都成功(一般有重试,或者换条路子重试)
重试就需要幂等,有些没办法直接重试,或者下游系统不然重试,或者由于前期的乐观数据已经有所变化,此时可能需要先查一下其他系统或者自己系统数据的状态,然后再决定如何重试,也是需要编排的

好处:1. 各系统的事务彻底隔离开了; 2. 现有的业务逻辑不变,专门针对出问题找办法解决
缺点:1. 需要编排,排查定位问题复杂; 2. 问题链路处理很复杂,有时候有系统不能回退(比如火箭已经发射,比如开发还没支持),有时其他系统不能重试,3. 只能保证最终一致性
那么我们可以让其他系统都支持回退或者重试吗,可以是可以,但是这个SAGA的初衷有些相互违背,因为TCC就是为了解决1%的问题,对99%的没有问题的情形改造,SAGA就是希望,各自99%,希望达到99.99999%的系统,自己来想办法保证
请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值