0%

分布式事务02_一致性算法-2PC&3PC

2PC

2PC,是Two- Phase Commit的缩写,即二阶段提交,是计算机网络尤其是在数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务处理过程中能够保持原子性和一致性而设计的一种算法。

阶段一:提交事务请求

  1. 事务询问。
    协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应

  2. 执行事务。
    各参与者节点执行事务操作,并将Undo和Redo信息记入事务日志中

  3. 各参与者向协调者反馈事务询问的响应。
    如果参与者成功执行了事务操作,那么就反馈给协调者Yes响应,表示事务可以
    执行;如果参与者没有成功执行事务,那么就反馈给协调者No响应,表示事务不
    丁以执行。由于上面讲述的内容在形式上近似是协调者组织各参与者对一次事务操作的投票表态过程,因此二阶段提交协议的阶段一也被称为“投票阶段”,即各参与者投票表明是否要继续执行接下去的事务提交操作。

阶段二:执行事务提交(两种情况)

在阶段二中,协调者会根据各参与者的反馈情况来决定最终是否可以进行事务提交操作,正常情况下,包含以下两种可能

执行事务提交

假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务提交。

  1. 发送提交请求
    协调者向所有参与者节点发出 Commit请求

  2. 事务提交。
    参与者接收到 Commit请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。

  3. 反馈事务提交结果
    参与者在完成事务提交之后,向协调者发送Ack消息

  4. 完成事务。
    协调者接收到所有参与者反馈的Ack消息后,完成事务

中断事务

假如任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应,那么就会中断事务。

  1. 发送回滚请求。
    协调者向所有参与者节点发出 Rollback请求。

  2. 事务回滚
    参与者接收到 Rollback请求后,会利用其在阶段一中记录的Undo信息来执
    行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。

  3. 反馈事务回滚结果。
    参与者在完成事务回滚之后,向协调者发送Ack消息

  4. 中断事务。
    协调者接收到所有参与者反馈的Ack消息后,完成事务中断。

2pc优缺点

优点:简单,实现方便
缺点:同步阻塞,单点问题,脑裂

同步阻塞:
二阶段提交协议存在的最明显也是最大的一个问题就是同步阻塞,这会极大地限制分布式系统的性能。在二阶段提交的执行过程中,所有参与该事务操作的逻辑都处于阻塞状态,也就是说,各个参与者在等待其他参与者响应的过程中,将无法进行其他任何操作。

单点问题:
协调者的角色在整个二阶段提交协议中起到了非常重要的作用。一旦协调者出现问题,那么整个二阶段提交流程将无法运转,更为严重的是,如果协调者是在阶段二中出现问题的话,那么其他参与者将会直处于锁定事务资源的状态中,而无法继续完成事务操作。

数据不一致:
在二阶段提交协议的阶段二,即执行事务提交的时候,当协调者向所有的参与者发送 Commit请求之后,发生了局部网络异常或者是协调者在尚未发送完 Commit请求之前自身发生了崩溃,导致最终只有部分参与者收到了 Commit请求。于是,这部分收到了 Commit请求的参与者就会进行事务的提交,而其他没有收到 Commit请求的参与者则无法进行事务提交,于是整个分布式系统便出现了数据不一致性现象。

3pc

3PC,是 Three-Phase commit的缩写,即三阶段提交,是2PC的改进版,其将二阶段提交协议的“提交事务请求”过程一分为二,形成了由CanCommit、 Pre Commit和 do commit三个阶段组成的事务处理协议。

阶段一: Can Commit

  1. 事务询问。
    协调者向所有的参与者发送一个包含事务内容的 can commit请求,询问是否可以执行事务提交操作,并开始等待各参与者的响应。

  2. 各参与者向协调者反馈事务询问的响应。
    参与者在接收到来自协调者的 can commit请求后,正常情况下,如果其自身认为可以顺利执行事务,那么会反馈Yes响应,并进入预备状态,否则反馈No响应。

阶段二: PreCommit

在阶段二中,协调者会根据各参与者的反馈情况来决定是否可以进行事务的 PreCommit操作,正常情况下,包含两种可能。(执行事务预提交或者中断事务)

执行事务预提交

假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务预提交。

  1. 发送预提交请求。
    协调者向所有参与者节点发出 pre Commit的请求,并进入 Prepared阶段。

  2. 事务预提交。
    参与者接收到 pre Commit请求后,会执行事务操作,并将Undo和Redo信息记录到事务日志中。

  3. 各参与者向协调者反馈事务执行的响应。

中断事务

假如任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应,那么就会中断事务。

  1. 发送中断请求。
    协调者向所有参与者节点发出 abort请求。

  2. 中断事务。
    无论是收到来自协调者的abor请求,或者是在等待协调者请求过程中出现超时,参与者都会中断事务。

阶段三: do commit

该阶段将进行真正的事务提交,会存在以下两种可能的情况。(执行提交中断事务)

执行提交

  1. 发送提交请求。
    进入这一阶段,假设协调者处于正常工作状态,并且它接收到了来自所有参与
    者的Ack响应,那么它将从“预提交”状态转换到“提交”状态,并向所有的
    参与者发送 docommit请求

  2. 事务提交
    参与者接收到 doCommit请求后,会正式执行事务提交操作,并在完成提交之
    后释放在整个事务执行期间占用的事务资源

  3. 反馈事务提交结果。
    参与者在完成事务提交之后,向协调者发送Ack消息

  4. 完成事务。
    协调者接收到所有参与者反馈的Ack消息后,完成事务。

中断事务

进入这一阶段,假设协调者处于正常工作状态,并且有任意一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应那么就会中断事务。

  1. 发送中断请求
    协调者向所有的参与者节点发送 abort请求。

  2. 事务回滚
    参与者接收到 abort请求后,会利用其在阶段二中记录的Undo信息来执行事
    务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。

  3. 反馈事务回滚结果。
    参与者在完成事务回滚之后,向协调者发送Ack消息

  4. 中断事务。
    协调者接收到所有参与者反馈的Ack消息后,中断事务。

一旦进入阶段三,可能会存在以下两种故障。

  1. 协调者出现问题
  2. 协调者和参与者之间的网络出现故障

无论出现哪种情况,最终都会导致参与者无法及时接收到来自协调者的 doCommit或是abort请求,针对这样的异常情况,参与者都会在等待超时之后,继续进行事务提交。

优缺点

优点

相对于二阶段提交,三阶段提交主要解决的单点故障问题,并减少了阻塞的时间。

因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行 commit而不会一直持有事务资源并处于阻塞状态。

缺点

三阶段提交也会导致数据一致性问题。由于网络原因,协调者发送的 abort 响应没有及时被参与者接收到,那么参与者在等待超时之后执行了 commit 操作。

这样就和其他接到 abort 命令并执行回滚的参与者之间存在数据不一致的情况。

一致性问题还是无法得到解决