• Home
  • Posts
    • All Posts
    • All Tags
  • Daily Summary
  • Technical Debt
  • Valuable Blog
  • Projects
  • About
    • Robin photo

      Robin

      Write Elegant Code.

    • Learn More
    • Email
    • Github

《从零开始学架构》笔记

分布式事务算法

2PC (two-phase commit protocol)

2PC 就是“2 阶段提交算法”,两个阶段分别是“请求阶段”和“提交阶段”

2PC 的前提

想要实现 2PC,整个系统需要满足一定的前提条件

  1. 在分布式系统中,存在一个协调者和多个参与者,且互相之间可以通信
  2. 所有节点都采用预写式日志
  3. 所有节点不会永久性损坏,即使损坏,也可以恢复

第一阶段:请求阶段

  1. 协调者向所有参与者发送 QUERY TO COMMIT 消息,询问是否可以执行提交事务,等待响应
  2. 参与者这个时候要把之前已经提交的事务执行完毕、在将新请求的 Undo 信息和 Redo 信息写入日志后返回 Yes;如果这些步骤失败,返回 No

第二阶段:提交阶段

  1. 协调者收到所有响应都是 Yes
    1. 协调者向所有参与者发出 COMMIT 请求
    2. 参与者完成 COMMIT 请求,释放资源
    3. 参与者响应 ACK
    4. 协调者收到所有 ACK 后,完成事务
  2. 协调者收到一个 No
    1. 协调者向所有参与者发出 ROLLBACK 请求
    2. 参与者完成 ROLLBACK 请求,释放资源。这一步是利用了第一阶段写入的 Undo 信息
    3. 参与者响应 ACK
    4. 协调者收到所有 ACK 后,取消事务

缺点

  • 同步阻塞,性能差
  • 状态不一致。在消息丢失的极端情况下会出现状态不一致的问题
  • 单点故障。只有一个协调者进行调度

3PC (three-phase commit protocol)

3PC 为了解决 2PC 的“单点故障”而生(在我看来,根本没解决嘛)

第一阶段:提交判断阶段

  1. 协调者向参与者发送 canCommit 消息,询问是否可以提交事务
  2. 参与者检查是否可以提交事务,返回 Yes 或 No
  3. 如果协调者收到 No,事务终止并通知参与者。如果全是 Yes,进入下一阶段

第二阶段:准备提交阶段

  1. 协调者发送 preCommit 消息给所有参与者,告诉参与者准备提交
  2. 参与者执行 preCommit,执行事务操作,然后将 Undo 和 Redo 记录到日志。响应 ACK

第三阶段:提交执行阶段

  1. 协调者收到所有 ACK 后发送 doCommit 消息,告诉参与者正式提交;否则发送回滚消息
  2. 参与者收到 doCommit 消息后提交事务,返回 haveCommited
  3. 如果参与者等待 doCommit 消息超时,会继续提交事务

缺点

除了单点故障稍稍改善了一点,另外俩毛病该有还是有

怎么改进 2PC 和 3PC?

Let’s discuss.