CAP理论

- 一致性:在分布式环境中,一致性是指数据在多个副本之间是否能够保持一致的特性,等同于所有节点访问同一份最新的数据副本。在一致性的需求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态。
- 可用性:每次请求都能获取到正确的响应,但是不保证获取的数据为最新数据。
- 分区容错性:分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。
CAP 理论是一个已经经过证实的理论,指出在一个分布式系统中最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。
BASE理论

- 基本可用:在分布式系统出现故障,允许损失部分可用性(服务降级、页面降级)。
- 软状态:允许分布式系统出现中间状态。而且中间状态不影响系统的可用性。这里的中间状态是指不同的 data replication(数据备份节点)之间的数据更新可以出现延时的最终一致性。
- 最终一致性:data replications 经过一段时间达到一致性。
BASE 理论是对 CAP 中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致性(CAP的一致性就是强一致性),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
分布式事务什么场景会产生?
- 单体项目多数据源情况下(跨数据库实例产生分布式事务)
- soa架构和微服务架构下(跨服务产生分布式事务)
分布式事务相关协议有哪些?
- 2PC:分为两个阶段,准备阶段、提交阶段
- 3PC:分为三个阶段,准备阶段、预提交阶段、提交阶段
描述下2PC

2PC,两阶段性提交协议:
- 准备阶段(Prepare phase):事务协调者给每个事务参与者发送Prepare消息,每个参与者在本地执行事务操作,但在执行完成后不会提交本地事务,而是先向协调者反馈事务能否处理成功。
- 提交阶段(commit phase):事务协调者根据反馈消息,选择回滚事物或提交事物。如果事务协调者接受到事务参与者执行失败或超时消息时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Conmmit)消息
2PC存在的问题:
- 同步阻塞:所有事务参与者在等待其它参与者响应的时候都处于同步阻塞状态,无法进行其它操作。
- 单点问题:协调者在 2PC 中起到非常大的作用,发生故障将会造成很大影响。列如:在第一阶段已经完成,在阶段二协调者发生故障,所有事务参与者会一直处于阻塞状态,无法完成其它操作。
- 数据不一致:在阶段二,如果协调者只发送了部分 Commit 消息,此时网络发生异常,那么只有部分参与者接收到 Commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。
- 太过保守:任意一个节点失败就会导致整个事务失败,没有完善的容错机制。
描述下3PC

3PC,三阶段性提交协议,是基于2PC的,添加了一个阶段,并添加超时机制和:
- 准备阶段(CanCommit):事务协调者询问事务参与者是否可以完成事务,在此阶段只是询问,防止某些事务参与者不可用情况下导致所有事务参与者都阻塞(不执行事务操作)。
- 预提交阶段(PreCommit):在准备阶段所有的事务参与者都返回可以执行操作时,事务协调者要求每个事务参与者预提交此操作,并反馈是否可以提交。(执行事务操作,但不提交,只是反馈是否可以成功提交)
- 提交阶段(DoCommit):事务协调者根据反馈消息,选择回滚事物或提交事物。如果每个事务参与者在预提交阶段返回准备成功,那么进行提交事。否则,进行回滚事物,释放资源。
- 超时机制:如果在预提交阶段超时,则中断事务,事务回滚;如果提交阶段超时,则事务参与者提交事物。
3PC优点:
- 降低了阻塞范围,在等待超时后协调者或参与者会中断事务
- 避免了协调者单点问题,阶段3中协调者出现问题时,参与者会继续提交事务。
3PC缺点:数据不一致问题依然存在,即在参与者收到PreCommit请求后等待最终指令,如果此时协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。
描述下2PC与3PC,它们的区别有哪些?
增加了一个询问阶段,询问阶段可以确保尽可能早的发现无法执行操作而需要中止的行为,但是它并不能发现所有的这种行为,只会减少这种情况的发生在准备阶段以后,协调者和参与者执行的任务中都增加了超时,一旦超时,协调者和参与者都继续提交事务,默认为成功,这也是根据概率统计上超时后默认成功的正确性最大。
三阶段提交协议与两阶段提交协议相比,具有如上的优点,但是一旦发生超时,系统仍然会发生不一致,只不过这种情况很少见罢了,好处就是至少不会阻塞导致永远锁定资源。
描述下TCC

TCC 是业务层面的分布式事务,分为三个阶段:
- Try阶段:是做业务检查以及资源预留(锁定)。此阶段仅是一个初步操作,需要和后续的Confirm阶段一起才能真正构成一个完整的业务逻辑。
- Confirm阶段:是做确认提交。Try阶段所有分支事务执行成功后开始执行 Confirm。通常情况下,采用TCC则 认为 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。若Confirm阶段真的出错了,需引入重试机制或人工处理。Confirm阶段需要保证幂等性。
- Cancel阶段:是做资源释放。Try阶段执行错误,取消执行Confirm阶段,调用Cancel阶段把Try阶段的操作撤销(回滚)了。通常情况下,Cancel阶段也是一定成功的。若Cancel阶段真的出错了,需引入重试机制或人工处理。Cancel阶段需要保证幂等性。
TCC和2PC/3PC很像,不过TCC的事务控制都是业务代码层面的,而2PC/3PC则是资源层面的。
TCC又可以被称为两阶段补偿事务,第一阶段try只是预留资源,第二阶段要明确的告诉服务提供者,这个资源你到底要不要,对应第二阶段的confirm/cancel,用来清除第一阶段的影响,所以叫补偿型事务。
分布式事务解决方案有哪些?
- XA:传统数据库实现的2PC
- 补偿机制TCC:补偿机制,是业务层面的分布式事务,可以认为是个2阶段性补偿事务
- 本地消息表:异步确保最终一致性
- 消息事务:基于MQ实现最终一致性
- 最大努力通知性:也是基于MQ实现最终一致性
Seata
Seata模块组件

Seata 中有三大模块,分别是 TM、RM 和 TC。
- TC (Transaction Coordinator):事务协调者;它是独立的中间件,需要独立部署运行。它维护全局和分支事务的状态,驱动全局事务提交或回滚。
- TM (Transaction Manager):事务管理器;定义全局事务的范围:开始全局事务、提交或回滚全局事务。
- RM (Resource Manager):资源管理器;管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

在 Seata 中,分布式事务的执行流程:
- TM 开启分布式事务(TM 向 TC 注册全局事务记录);
- 按业务场景,编排数据库、服务等事务内资源(RM 向 TC 汇报资源准备状态 );
- TM 结束分布式事务,事务一阶段结束(TM 通知 TC 提交/回滚分布式事务);
- TC 汇总事务信息,决定分布式事务是提交还是回滚;
- TC 通知所有 RM 提交/回滚 资源,事务二阶段结束。
AT模式
AT模式是两阶段提交协议(2PC)的演变:
- 阶段1:将业务数据和回滚日志记录在同一个本地事务提交,释放本地锁和连接资源(不阻塞)
- 阶段2:
- 分支事务全部完成,触发全局提交,不需要同步协调处理(只需要异步清除回滚日志)
- 分支事务发来回滚请求,触发全局回滚,RM通过回滚日志完成分支事务的回滚。
AT模式主要流程:
- TM请求TC,开启一个全局事务,全局事务创建成功并生成唯一的XID
- RM向TC注册事务分支,并且执行本地事务逻辑,TC将事务分支纳入XID对应全局事务的管辖
- XID通过服务调用链,传递到其他服务中(其他RM)
- 当RM分支事务执行全部完成或有RM分支事务执行异常,TM向TC发起针对XID的全局事务提交或回滚
- TC调度XID下管辖的全部RM分支事务完成提交或回滚请求。
核心概念:
- 每个RM使用DataSourceProxy连接数据库,其目的是使用ConnectionProxy,使用数据源和数据连接代理的目 的就是在第一阶段将undo_log和业务数据放在一个本地事务提交,这样就保存了只要有业务操作就一定有 undo_log。
- 在第一阶段undo_log中存放了数据修改前和修改后的值,为事务回滚作好准备,所以第一阶段完成就已经将分 支事务提交,也就释放了锁资源。
- TM开启全局事务开始,将XID全局事务id放在事务上下文中,通过feign调用也将XID传入下游分支事务,每个 分支事务将自己的Branch ID分支事务ID与XID关联
- 第二阶段全局事务提交,TC会通知各各分支参与者提交分支事务,在第一阶段就已经提交了分支事务,这里各 各参与者只需要删除undo_log即可,并且可以异步执行,第二阶段很快可以完成。
- 第二阶段全局事务回滚,TC会通知各各分支参与者回滚分支事务,通过 XID 和 Branch ID 找到相应的回滚日 志,通过回滚日志生成反向的 SQL 并执行,以完成分支事务回滚到之前的状态,如果回滚失败则会重试回滚操作