分布式事务综述
理论知识 事务的四个特性:ACID Atomic 原子性:一个事务中的所有操作,要么全部完成,要么全部不完成 Consistency 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。完整性包括外键约束、应用定义等约束不会被破坏 Isolation 隔离性:防止多个事务并发执行时由于交叉执行而导致数据的不一致 Durability 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失 分布式系统三个特性:CAP Consistency 一致性:集群执行某个操作后,所有副本节点的状态都相同,那么这样的系统就被认为具有强一致性 Available 可用性:集群一部分节点故障后,还能对外提供服务 Partition tolerance 分区容忍性:狭义上是集群节点之间是否能正常通信,更广义的是对通信的时限要求,系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况 对于互联网的场景来说,一般选择AP:因为现在集群规模越来越大,主机众多、部署分散,所以节点故障、网络故障是常态,而且要保证服务可用性达到N个9,即保证P和A,舍弃C。 分布式的BASE理论:柔性事务,对CAP的权衡 Basically Available 基本可用:系统在出现不可预知故障的时候,允许损失部分可用性,但这绝不等价于系统不可用 Soft state 软状态:允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性 Eventually consistent 最终一致性:经过一段时间的同步后,最终能够达到一个一致的状态 NewSQL的分布式事务: 以Spanner、TiDB为代表的NewSQL,在内部集群多节点间,实现了ACID的事务,即提供给用户的事务接口与普通本地事务无差别,但是在内部,一个事务是支持多个节点多条数据的写入,此时无法采用本地ACID的MVCC技术,而是会采用一套复杂的分布式MVCC来做到ACID。属于满足CP的系统,同时接近于满足A,称之为CP+HA。但是NewSQL和BASE的系统之间,性能上差异可能是巨大的。 跨库跨服务的分布式事务:这类分布式事务部分遵循 ACID 原子性:严格遵循 一致性:事务完成后的一致性严格遵循;事务中的一致性可适当放宽 隔离性:并行事务间不可影响;事务中间结果可见性允许安全放宽 持久性:严格遵循 现有的分布式事务方案都无法做到强一致,但是有强弱之分:XA事务 > TCC > 二阶段消息 > SAGA(一般情况下)。具体为: XA:XA虽然不是强一致,但是XA的一致性是多种分布式事务中,一致性最好的,因为他处于不一致的状态时间很短,只有一部分分支开始commit,但还没有全部commit的这个时间窗口,数据是不一致的。因为数据库的commit操作耗时,通常是10ms内,因此不一致的窗口期很短。 TCC:理论上,TCC可以用XA来实现,例如Try-Prepare,Confirm-Commit,Cancel-Rollback。但绝大多数时候,TCC会在业务层自己实现Try|Confirm|Cancel,因此Confirm操作耗时,通常高于XA中的Commit,不一致的窗口时间比XA长 MSG:二阶段消息型事务在第一个操作完成后,在所有操作完成之前,这个时间窗口是不一致的,持续时长一般比前两者更久。 SAGA:SAGA的不一致窗口时长与消息接近,但是如果发生回滚,而子事务中正向操作修改的数据又会被用户看到,这部分数据就是错误数据,容易给用户带来较差的体验,因此一致性是最差的。 2PC 两阶段提交流程如下: 准备阶段:RM去开启事务并执行操作,但是不提交事务,此时相关资源都被锁定,第三方不能访问这些资源。返回操作结果给TM 提交阶段:若所有RM在准备阶段都操作成功,TM将发出请求让所有RM提交事务,否则发出请求让所有RM回滚 存在问题: 同步阻塞:从准备阶段的锁定资源,直到事务提交/回滚的过程中,资源都处于被RM锁定的状态,第三方访问会被阻塞。 单点故障:2PC的推进重度依赖TM,TM若发生故障,RM会被阻塞。 数据不一致:若提交阶段部分RM无法与TM正常通信,导致一部分子事务提交了,而发生异常的RM没提交,全局事务发生不一致。 3PC 3PC提交将2PC的准备阶段再次拆分,加入检查阶段,如果检查失败的话马上abort,减少了2PC在失败情况下白白浪费资源,并且引入RM的超时机制(2PC只有TM超时机制),如果在提交阶段TM超时,直接提交事务释放资源。3PC流程如下: 检查阶段:TM 询问 RM,是否具备执行事务的条件,RM 进行自身事务必要条件的检查 预提交阶段:TM 通知 RM 进行事务的预提交 提交阶段:TM 根据预提交阶段 RM 的反馈结果通知 RM 是否进行事务提交或是进行事务回滚 RM超时自动提交是因为此时已经进入了提交阶段,说明RM知道检查阶段已经成功(但是RM不知道预提交阶段是否成功),认为第三阶段很大概率也可以成功。但很明显,如果第二步存在RM失败了,即预提交失败,因此在第三步中,TM发出回滚请求,但此时又有另外一个RM超时并自动提交了事务(超时时间内收不到回滚请求),就会出现不一致。 ...