前言
相关系列
分布式事务
所谓分布式事务是指操作范围笼罩多个不同节点的事务。例如对于订单节点&库存节点而言,一次完整的交易需要同时调动两个节点。而如果将这个交易的所有操作作为ACID事务执行,那么该事务就被称为分布式事务。
2PC @ 2 Phase Commit @ 二阶段递交
2PC&3PC协议是处理分布式事务数据一致性(与CAP理论的一致性不同,事务的一致性是指确保数据在两个“合法”状态间的“正确转移”)问题的解决方案,其本质是通过确保事务的原子性来保证一致性。在分布式系统中,节点虽然可以知晓自身操作的成功与否,但却无法知晓其他节点操作的执行结果。因此当事务跨越多个节点时,为了保持事务的原子性&一致性,需要引入了TM @ 事务管理器来统一掌握所有RM @ 资源管理器的操作结果,并决定是否把各资源管理器的操作结果统一提交/回滚。2PC协议分为准备&提交两个阶段:
- Prepare phase @ 准备阶段:事务管理器会向所有资源管理器发送(2PC/3PC/TCC协议都只是分布式事务的实现思想,因此事务管理器对资源管理器的请求发送无需在意串/并行,但具体的实现工具/框架就必须考虑这一点,因为各个资源管理器事务之间可能存在依赖性,例如事务B的执行需要事务A的执行结果参与)“准备”请求以确认其是否已准备好递交事务。资源管理器在收到“准备”请求后会开启&执行本地事务,但并不真正递交,而是将Undo和Redo日志写入本地事务日志中。Undo日志用于记录如何回滚事务,而Redo日志则用于在提交阶段重新执行事务操作。尽管在2PC中通常不直接使用Redo日志提交,但它在某些故障恢复场景中是有用的。本地事务执行结束后,将成功与否以Yes/No的形式回应至事务管理器;
- Commit phase @ 递交阶段:如果事务管理器收到所有反馈且发现资源管理器都已成功执行本地事务则会决定提交事务,否则就回滚事务。各节点在收到事务管理器发送的“递交/回滚”请求后会统一将各自的执行结果递交/回滚。
缺点
- 同步阻塞:在整个分布式事务未结束前,所有资源管理器(的事务涉及业务)都会处于阻塞状态;
- 单点故障:事务管理器是整个分布式事务的核心,如果事务管理器宕机,那么所有资源管理器都会被锁定而无法继续执行;
- 数据不一致:二阶段如果出现网络分区/节点宕机而导致部分资源管理器未收到事务递交指令/事务递交失败,那么就会出现数据不一致的情况。
3PC @ 3 Phase Commit @ 三阶段递交
3PC协议在2PC协议的基础上引入了检查/超时机制,用于避免/处理2PC的“同步阻塞/单点故障/数据不一致”问题。3PC协议分为以下三个阶段:
- CanCommit @ 可/询问递交:事务管理器向各资源管理器询问是否可以支持执行/提交事务。各资源管理器接收到询问后根据自身情况向事务管理器返回Yes/No回应。如果事务管理器没有在指定时间内接收到所有回应/接收到No回应,则分布式事务中断/取消。可/询问递交阶段是3PC协议引入的新阶段,目的是事先检查资源管理器的状态能否支持分布式事务的执行/递交,从而避免无意义的分布式事务执行以增强协议的可靠性&容错率;
- PreCommit @ 预提交:在接收到所有Yes回应的情况下,分布式事务会进入预递交阶段。该阶段中事务管理器会向各资源管理器发送预递交请求,而接收到请求的各资源管理器会开启&执行本地事务但不递交,并将Undo和Redo日志写入本地事务日志中,随后向事务管理器发送Ack回应。而如果事务管理器没有在指定时间内接收到所有Ack回应/接收到Abort回应,则事务管理器会向各资源管理器发送Abort请求,从而令各资源管理器回滚本地事务。而在这阶段中如果部分已开启&执行本地执行的资源管理器未能在指定时间内接收到Abort请求,则其也会因为超时而自动回滚本地事务;
- DoCommit @ 最终提交:在接收到所有Ack回应后,分布式事务会进入最终递交阶段。该阶段中事务管理器会向各资源管理器发送最终递交请求,而接收到请求的各资源管理器会递交事务,并向事务管理器发送Ack回应表示事务递交已完成。注意!该阶段中而如果有部分资源管理器未能在指定时间内接收到最终递交请求,则该资源管理器就可能因为超时而自动回滚本地事务,从而无法保证分布式事务的原子性,并进一步破坏数据一致性。因此3PC协议同样无法完全避免2PC协议的数据不一致问题。
优点
- 可靠性&容错率提升:检查机制增强了分布式事务的可靠性&容错率;
- 超时机制减少了对阻塞时间:超时机制减少了资源管理器等待事务管理器指令的阻塞时间;
- 减少了单点故障对系统的影响:超时机制降低了事务管理器单点故障对系统的影响。
缺点
- 复杂性增加:3PC协议相比2PC协议而言需要处理更多状态转换&超时逻辑,这为增加了实现的难度&出错的可能性;
- 性能开销:更复杂的流程同步带来了是性能开销的增加;
- 数据不一致:3PC协议依然未能解决数据不一致问题,虽然检查&超时有助于降低这一点,但网络分区造成的数据不一致问题依然是存在的。
TCC @ Try Confirm Cancel @ 尝试确认取消
TCC协议是一种不同于2PC/3PC协议的分布式事务解决方案,其核心思想是“补偿机制”,即在分布式事务出现异常/失败时通过执行相反的操作来补偿之前的行为,从而达到事务的一致性。TCC将分布式事务划分为以下三个阶段:
- Try @ 尝试:事务管理器向事务协调器申请开启分布式事务并获得全局事务ID,随后将该全局事务ID发送至各资源管理器。资源管理器接收到全局事务ID后会向事务协调器注册分支事务ID,从而将分支事务ID纳入该全局事务ID下管理。此后资源管理器便会开启&执行本地事务并预留必要的资源,以便后续递交事务时使用,并向事务管理器报告当前分支事务的开启&执行情况;
- Confirm @ 确认:如果在尝试阶段中的所有的资源管理器都成功开启&执行了本地事务,那么分布式事务就会进入确认阶段。在确认阶段中事务管理器会向各资源管理器发送确认请求,从而令其能够真正的递交事务,并于事务管理器中标记分支事务已成功递交;
- Cancel @ 取消:如果在尝试&确认阶段中存在资源管理器未能成功开启&执行&递交本地事务的情况,那么分布式事务就会进入取消阶段。在取消阶段中事务管理器会向各资源管理器发送取消请求,从而回滚尚未递交的事务/执行相反的操作弥补已递交的事务,并于事务管理器中标记分支事务已成功取消。而对于因为各种原因未能接收到取消请求的资源管理器,由于超时机制的存在其也会自动执行取消行为,从而极大程度的确保了事务的原子性。
优点
- 极大确保了原子性:补偿机制的存在使得已递交的事务也可以被取消,从而降低因为网络分区而数据不一致的风险;
- 避免数据库锁冲突的低性能风险:TCC通过将数据库的二阶段提交上升到微服务来实现,避免了数据库二阶段提交中锁冲突导致的长事务低性能风险;
- 异步高性能:TCC采用了先try检查,然后异步实现confirm的方式,提高了系统的性能和可扩展性。
缺点
- 侵入性强:微服务的每个事务都必须实现Try/Confirm/Cancel三个方法,增加了开发成本和后期维护改造的成本;
- 等幂性:为了达到事务的一致性要求,Try/Confirm/Cancel接口必须实现等幂性操作,这增加了实现的复杂性;
- 事务日志损耗性能:事务管理器需要记录事务日志,这必定会损耗一定的性能,并可能使得整个TCC事务时间拉长。