异度部落格

学习是一种生活态度。

0%

分布式系统理论 - 两段式提交(2PC)和三段式提交(3PC)

之前BASE 理论中提到,分布式系统对一致性做出了权衡。因此涌现出很多分布式协议。其中比较著名的是:两段式提交(Two Phase Commit)和三段式提交(Three Phase Commit)。

两段式提交

定义

每个参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报,决定各参与者是否要提交操作还是中止操作。

2pc

所谓的两个阶段分别是:

第一阶段:准备阶段/投票阶段

  1. 协调者节点向所有参与者节点询问是否可以执行提交操作,并开始等待各参与者节点的响应。
  2. 参与者节点执行询问发起为止的所有事务操作,并将 Undo 信息和 Redo 信息写入日志。
  3. 各参与者节点响应协调者节点发起的询问。如果参与者节点的事务操作实际执行成功,则它返回一个"同意"消息;如果参与者节点的事务操作实际执行失败,则它返回一个"中止"消息。

第二阶段:提交阶段/执行阶段

当协调者节点从所有参与者节点获得的相应消息都为"同意"时:

  1. 协调者节点向所有参与者节点发出"正式提交"的请求。
  2. 参与者节点正式完成操作,并释放在整个事务期间内占用的资源。
  3. 参与者节点向协调者节点发送"完成"消息。
  4. 协调者节点收到所有参与者节点反馈的"完成"消息后,完成事务。

如果任一参与者节点在第一阶段返回的响应消息为"终止",或者 协调者节点在第一阶段的询问超时之前无法获取所有参与者节点的响应消息时:

  1. 协调者节点向所有参与者节点发出"回滚操作"的请求。
  2. 参与者节点利用之前写入的 Undo 信息执行回滚,并释放在整个事务期间内占用的资源。
  3. 参与者节点向协调者节点发送"回滚完成"消息。
  4. 协调者节点收到所有参与者节点反馈的"回滚完成"消息后,取消事务。

优缺点

  • 优点:原理简单,实现方便。
  • 缺点:同步阻塞,单点问题,数据不一致,容错性不好

三段式提交

定义

由于两段式提交存在诸多缺陷,因此研究者在两段式基础上进行改进,实现了三段式提交。与两阶段提交不同的是,三阶段提交有两个改动点:

  • 引入超时机制 - 同时在协调者和参与者中都引入超时机制。
  • 在第一阶段和第二阶段中插入一个准备阶段,保证了在最后提交阶段之前各参与节点的状态是一致的。

3pc

所谓的三个阶段分别是:

第一阶段:CanCommit

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

第二阶段:PreCommit

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

第三阶段:Do Commit

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

优缺点

  • 优点:相对于二阶段提交,三阶段提交主要解决的单点故障问题,并减少了阻塞的时间。
  • 缺点:三阶段提交也会导致数据一致性问题。由于网络原因,协调者发送的 abort 响应没有及时被参与者接收到,那么参与者在等待超时之后执行了 commit 操作。这样就和其他接到 abort 命令并执行回滚的参与者之间存在数据不一致的情况。

参考资料

  • https://en.wikipedia.org/wiki/Two-phase_commit_protocol
  • https://en.wikipedia.org/wiki/Three-phase_commit_protocol
  • https://juejin.im/post/5b26648e5188257494641b9f