type
status
date
slug
summary
tags
category
icon
password

CAP原则

CAP原则指一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性),这三个最多同时满足其中的2个
notion image
一致性(C):数据在多个副本之间保证一致特性(严格的一致性)
可用性(A):系统的服务必须一直处于可用状态,每次请求都能得到非错的响应
分区容错性(P):某个分区数据发生故障时,系统仍可以正常运行

CA without P

如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。

CP without A

如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。

AP without P

要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据不一致性。互联网常用选择模式。

BASE理论

基本可用(Basically Available):响应时间变慢,功能上降级处理
软状态(Soft State):允许节点存在中间状态,数据有延迟
最终一致性(Eventually Consistent):软状态数据超过一定时间,需保证最终一致

最终一致性的五种形式

因果一致性:如果节点A在更新完某个数据后通知了节点B,那么节点B之后对该数据的访问和修改都是基于A更新后的值。于此同时,和节点A无因果关系的节点C的数据访问则没有这样的限制。
读己之所写:节点A更新一个数据后,它自身总是能访问到自身更新过的最新值,而不会看到旧值。其实也算一种因果一致性。
会话一致性:将对系统数据的访问过程框定在了一个会话当中:系统能保证在同一个有效的会话中实现 “读己之所写” 的一致性,也就是说,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。
单调读一致性:如果一个节点从系统中读取出一个数据项的某个值后,那么系统对于该节点后续的任何数据访问都不应该返回更旧的值。
单调写一致性:一个系统要能够保证来自同一个节点的写操作被顺序的执行。

XA规范

  • 应用程序( AP )
  • 事务管理器( TM ):交易中间件等
  • 资源管理器( RM ):关系型数据库等
  • 通信资源管理器( CRM ):消息中间件等
XA规范定义了交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。而XA接口函数由数据库厂商提供。
二阶提交协议和三阶提交协议就是基于XA规范提出的其中,二阶段提交就是实现XA分布式事务的关键。
notion image

两阶段提交(2PC)

二阶段提交协议(Two-phase commit protocol)简称 2PC。两阶段提交是一种强一致性事务协议,它分为准备阶段和提交阶段。有熟悉 MySQL 的同学可能马上就能想到,MySQL 的事务提交就是通过几种日志来实现二阶段提交的。

准备阶段

○ 协调者向所有参与者询问是否可以提交事务,同步等待各参与者的响应。
○ 参与者执行本地事务操作,并将Undo信息和Redo信息写入日志。
○ 各参与者响应协调者发起的询问。如果参与者的事务执行成功,则返回YES信号;如果参与者的事务执行失败,则返回NO信号。

提交阶段

1) 成功:当协调者从所有参与者获得的响应都为YES时:
○ 协调者向所有参与者发出Commit请求。
○ 参与者正式完成操作,释放在整个事务期间内占用的资源,参与者向协调者发送Committed消息。
○ 协调者收到所有参与者反馈的Committed消息后,完成事务。
notion image
2) 失败:如果任一参与者在第一阶段返回NO信号,或者协调者在第一阶段响应超时:
○ 协调者向所有参与者发出Rollback请求。
○ 参与者利用写入的Undo信息回滚本地事务,释放各自占用的资源,参与者向协调者发送Rollbacked消息。
○ 协调者收到所有参与者反馈的Rollbacked消息后,取消事务。
notion image

2PC优点

  • 原子性保证: 2PC 协议可以保证所有参与者要么全部提交成功,要么全部失败回滚,从而实现跨多个分布式节点的事务的原子性。
  • 简单直观: 2PC 的设计思路简单,逻辑清晰,容易理解,这使得它在很多传统的数据库和分布式系统中得到了广泛的应用,比如 MySQL 从 5.5 版本开始支持。

2PC缺点

  • 同步阻塞: 在 2PC 的第一阶段,所有参与者在响应协调者的准备请求后,必须等待最终的提交或回滚指令。这期间,所有参与者都处于阻塞状态,无法进行其他操作,导致资源锁定时间较长,在高并发场景下很明显不太适用。
  • 单点故障: 如果协调者在第二阶段崩溃,参与者可能会无限期地等待指令,因为它们不知道应该提交还是回滚。这使得整个系统容易受到单点故障的影响。
  • 数据不一致: 如果在第二阶段中协调者向某些参与者发送了提交指令,而其他参与者因为网络问题没有收到指令,那么这些没有收到指令的参与者可能会选择回滚,导致数据不一致。
  • 复杂的恢复机制: 当系统崩溃后,恢复过程非常复杂,所有参与者必须保持足够的信息以便在系统恢复后能够继续完成 2PC 协议。

三阶段提交(3PC)

三阶段提交(Three-phase commit),是二阶段提交(2PC)的改进版本。不同的是,三阶段提交有两个改进点,有效解决长时间阻塞和协调者单点故障
  • 引入超时机制
  • 把准备阶段拆分为两个阶段
📌
如果此时某个参与者无法完成提交,所有参与者都做了无用功。所以,增加一轮询问阶段,这个阶段参与者并不真正获取锁和占用资源,只是对自身事务状态的检查,查看是否具备执行事务的条件。

CanCommit

  • 事务询问,协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应。
  • 响应反馈,参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态;否则反馈No。

PreCommit

  • 发送预提交请求,协调者向所有参与者节点发出 preCommit 的请求,并进入 prepared 状态。
  • 事务预提交,参与者受到 preCommit 请求后,会执行事务操作,对应 2PC 准备阶段中的 “执行事务”,也会 Undo 和 Redo 信息记录到事务日志中。
  • 各参与者响应反馈,如果参与者成功执行了事务,就反馈 ACK 响应,同时等待指令:提交(commit) 或终止(abort)。

Do Commit

  • 发送提交请求,协调者接收到各参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送 doCommit 请求。
  • 事务提交,参与者接收到 doCommit 请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。
  • 响应反馈,事务提交完之后,向协调者发送 ACK 响应。
  • 完成事务,协调者接收到所有参与者的 ACK 响应之后,完成事务。

TCC事务

TCC(Try-Confirm-Cancel)是一种 应用层 的分布式事务解决方案,本质上属于 补偿性事务模式,它将事务分为三个步骤:尝试(Try)、确认(Confirm)和取消(Cancel) :对应用的侵入性较强,需考虑幂等性,空回滚等。

Try

在Try阶段,事务发起方进行资源检查和预留,预留好事务需要用到的所有业务资源。
Try 阶段可能会重复执行,因此需要满足幂等性,同时需要需要支持防悬挂控制,比如:Try超时,Cancel先到,Try后到场景,需要Cancel记录事务id,Try对于该id拒绝执行;
比如交易系统,库存预扣减,积分预增加,修改订单状态

Confirm

如果所有参与者在Try阶段都执行成功,事务发起方会发送确认请求,要求各个参与者执行真正的提交操作。
Confirm 阶段可能会重复执行,因此需要满足幂等性。

Cancel

如果任何一个参与者在Try阶段执行失败,或者Confirm阶段执行失败,事务发起方会发送取消请求,要求各个参与者执行回滚操作,撤销Try阶段的操作。
Cancel阶段可能会重复执行,因此需要满足幂等性;同时允许空回滚,比如Try消息丢失,需要Cancel请求时返回成功。

空回滚问题

原因:出现空回滚的原因是一个分支事务所在的服务器宕机或者网络发生异常,此分支事务调用失败,此时并未执行此分支的Try阶段的方法,当服务器或者网络恢复后,TCC分布式事务执行回滚操作,会调用分支事务的Cancel阶段的方法,如果Cancel阶段的方法不能处理这种情况,就会出现空回滚的问题 解决方案:识别是否出现空回滚操作的方法是判断是否执行了Try阶段的方法,如果执行了Try阶段的方法,就没有空回滚,否则则出现空回滚

幂等问题

原因:由于服务器宕机、应用崩溃或者网络异常等原因,可能会出现方法调用超时的情况,为了保证方法的正常执行,往往会在TCC方案中加入超时重试机制,因为超时重试有可能导致数据的不一致问题,所以需要保证分支事务的执行以及TCC方案的Confirm阶段和Cancel阶段具备幂等性 解决方案:在分支事务记录表中增加事务的执行状态,每次执行分支事务以及Confirm阶段和Cancel阶段的方法时,都查询次事务的执行状态,以此判断事务的幂等性

悬挂问题

原因:TCC分布式事务中,通过RPC调用分支事务Try阶段的方法时,会先注册分支事务,在执行RPC调用。如果此时发生服务器宕机,应用崩溃或者网络异常等情况,RPC调用就会超时,如果RPC调用超时,事务管理器会通知对于的资源管理器回滚事务,可能资源管理器回滚完事务后,RPC请求达到了参与分支事务所在的业务方法,因为此时事务以及回滚,所以在Try阶段预留的资源就无法释放了,这种情况下,就成为悬挂 解决方案:如果执行了Confirm阶段或者Cancel阶段的方法,则Try阶段的方法就不能再执行了,具体方案是在执行Try阶段的方法时,判断分支记录表中是否存在同一全局事务下Confirm阶段或者Cancel阶段的事务记录,如果存在,则不执行Try阶段的方法