分布式学习手记02 - 一致性协议:二、三阶段提交

1 分钟读完

分布式事务跨越多个节点,为保持事务处理的 ACID 特性,需要一个“协调者”(Coordinator)组件来统一调度所有分布式节点——“参与者”(Participant)的执行逻辑。

协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务真正进行提交。

两阶段提交 2PC

2PC - 2 Phase Commit 为了使所有分布式节点在事务处理过程中,保持原子性和一致性而设计的算法。

Phase 1 投票

第一阶段:提交事务请求

  • 事务询问 ->

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

  • 执行事务 ->

    各参与者执行事务,并将 Undo 信息和 Redo 信息写入日志(此处 Redo 的参与者已完成事务执行);

  • 参与者响应协调者事务执行询问 ->

    Redo 的参与者向协调者发送 Yes 响应,表是事务可以执行,Undo 的参与者发送 No 响应,表示事务无法执行;

Phase 2 执行

第二阶段:执行事务提交

协调者会根据参与者反馈决定是否进行事务提交操作(收到 No 响应或等待超时,则向参与者发送回滚消息,否则提交消息),并释放事务处理过程中使用的锁资源。

所以该阶段包含两种可能:

a- 参与者反馈都是 Yes 响应,执行事务提交:

  • 发送请求提交 ->

    上阶段最后一步协调者收到 Yes 响应,于是向参与者发出 Commit 请求;

  • 事务提交 ->

    参与者收到 Commit 请求,正式执行事务提交操作,完成后释放执行事务期间站占用的资源;

  • 反馈事务提交结果 ->

    参与者完成事务提交后,向协调者发送 ACK 消息;

  • 完成事务 -|

    协调者收到所有参与者的 ACK 消息后,完成事务。

b- 若有参与者反馈 No 响应,或协调者等待响应超时,中断事务:

  • 发送回滚请求 ->

    上阶段最后一步协调者收到 No 响应,则向参与者发出 Rollback 请求;

  • 事务回滚 ->

    参与者收到 Rollback 请求后,利用上阶段的 Undo 信息执行事务回滚操作,并在完成后释放执行事务期间占用的资源;

  • 反馈事务回滚结果 ->

    参与者完成事务回滚后,向协调者发送 ACK 消息;

  • 中断事务 -|

    协调者收到所有参与者的 ACK 消息后,完成事务中断。

缺点

  • 同步阻塞

    响应过程中,参与者阻塞等待,极大限制系统性能

  • 单点问题

    协调者若发生故障后果严重

  • 数据不一致

    第二阶段,若部分参与者没收到 Commit 消息,则与收到 Commit 消息的参与者事务操作产生差异,系统数据不再一致

  • 保守

    失败或超时,没有较为完善的容错机制

三阶段提交

3PC - 3 Phase Commit 两阶段提交的改进版,优化二阶段提交中参与者和协调者都挂掉的情况

Phase 1 CanCommit

  • 事务询问 ->

    协调者向参与者发送包含事务内容的 CanCommit 请求,等待响应;

  • 参与者响应 ->

    参与者收到 CanCommit 请求后,评估是否能执行事务,根据评估结果反馈 Yes / No 响应;

Phase 2 PreCommit

预提交阶段,协调者根据参与者反馈决定是否进行事务 PreCommit 操作,因此有两种情况:

a- 协调者收到全是 Yes 反馈,执行事务预提交

  • 发送预提交请求 ->

    协调者向参与者发送 PreCommit 请求,进入 Prepared 状态;

  • 事务预提交 ->

    参与者收到 PreCommit 请求后,执行事务操作,并根据执行结果,记录 Undo / Redo 信息;

  • 参与者反馈事务执行响应 ->

    若参与者成功执行事务,给协调者发送 ACK 响应,等待最终指令(提交或终止);

b- 协调者收到部分 No 反馈,或等待超时,中断事务

  • 发送中断请求 ->

    协调者向参与者发送 Abort 请求;

  • 中断事务 -|

    参与者收到 Abort 请求,或等待超时,则中断事务。

Phase 3 DoCommit

本阶段进行真正的事务提交,根据预提交阶段参与者事务执行的反馈结果,存在两种可能:

a- 执行提交

  • 发送提交请求 ->

    协调者收到参与者执行成功呃 ACK 响应,则从“预提交”状态切换到“提交”状态,并向所有参与者发送 DoCommit 请求;

  • 事务提交 ->

    参与者收到 DoCommit 请求后,正式执行事务提交操作,完成后释放事务执行期间占用的资源;

  • 反馈事务提交结果 ->

    参与者完成事务提交后,向协调者发送 ACK 消息;

  • 完成事务 -|

    协调者接收到所有参与者的 ACK 消息后,完成事务。

b- 中断事务

预提交阶段,协调者若收到参与者 PreCommit 操作失败反馈或等待超时,则中断事务

  • 发送中断请求 ->

    协调者向参与者发送 Abort 请求;

  • 事务回滚 ->

    参与者收到 Abort 请求后,会利用 Undo 信息执行事务回滚操作,完成后释放占用资源;

  • 反馈事务回滚结果 ->

    参与者完成事务回滚后,向协调者发送 ACK 消息;

  • 中断事务 -|

    协调者接收到所有参与者的 ACK 消息后,中断事务。

优缺点

  • 3PC 相对 2PC 优点在于第一阶段降低参与者的阻塞,并弥补 2PC 参与者和协调者都挂掉带来的数据不一致问题。

  • 3PC 在 DoCommit 阶段也会有数据不一致的风险,具体可以参考 深入理解分布式系统的2PC和3PC 这篇文章。

分类:

更新时间: