分布式系统知识点

拜拜、爱过 提交于 2019-12-11 07:57:29

2PC

全称二阶段提交(two phase commit), 用于实现分布式事务的原子性. 即对于一个操作, 保证所有节点要么都执行, 要么都不执行.

由于不同节点不能直接获取其他节点的操作执行情况, 因此算法引入一个协调者(coordinator), 执行操作的节点称为参与者.
由参与者向协调者通知其操作的执行结果, 协调者根据结果通知所有参与者中止/提交操作.

算法分为两个阶段: 准备(Prepare)阶段和提交(Commit)阶段, 又称为投票阶段和执行阶段.

  1. 准备阶段

    协调者给每个参与者发送 prepare 消息, 通知参与者执行操作. 参与者要么返回失败(例如权限验证失败),
    要么写本地的 redo 和 undo 日志, 并执行此操作, 但是不提交, 然后返回成功的消息.

  2. 提交阶段

    协调者发送完 prepare 消息后, 就进入本阶段, 等待参与者的回复.
    如果所有参与者都回复成功, 那么协调者再向每个参与者发送 commit 消息, 通知其 commit 此操作.
    否则, 向所有参与者发送 rollback 消息, 通知其回滚此操作. 参与者的回复超时也会导致此结果.
    参与者收到 commit 消息后, 就会将操作提交, 并释放操作执行期间占用的资源.
    如果参与者收到 rollback 消息, 则会利用 undo 日志回滚操作, 并释放占用的资源.
    完成提交/回滚操作后, 参与者向协调者返回 ack 消息. 协调者收到所有参与者的 ack 后, 事务完成.

2PC 原理简单, 容易实现, 但是存在几个问题:

  • 同步阻塞: 执行过程中参与者占据着公共资源, 其他需要使用资源的操作将会被阻塞.
  • 单点问题: 协调者如果出现故障, 事务将无法完成. 可以采用多个备份协调者来处理此问题,
    但是在新的协调者启动前事务无法向前推进.
  • 数据不一致: 在提交阶段, 协调者发送 commit 消息后故障, 并且只有部分参与者收到 commit 消息,
    这就导致了参与者的数据不一致. 并且, 如果只有一个参与者收到 commit 消息, 并且随后此节点也故障停机,
    后面即使新的协调者产生, 也无法确定整个系统的状态.

各个阶段可能出现的错误(这里只考虑fail-stop)及对应的解决方案.

3PC

3PC 在 2PC 的基础上, 加入了一个阶段用于检查各个参与者是否可以执行事务, 此阶段并不会执行事务.
三个阶段分别是 canCommit, preCommit, doCommit.
此外, 还在协调者和参与者中引入超时机制, 以应对 2PC 中 commit 消息丢失导致的不一致问题.
但是 3PC 仍然无法保证完全一致.

  1. canCommit

    1. 协调者向参与者发送 canCommit 消息, 等待(waiting state)参与者回复.
    2. 参与者收到 canCommit 消息后, 如果认为可以执行事务, 返回 Yes, 进入 Prepared 状态,
      等待 preCommit 消息. 如果否则返回 No, 终止事务.
  2. preCommit

    1. 协调者在规定时间内收到所有参与者的 Yes 消息后, 向每个参与者发送 preCommit 消息,
      进入 Prepared 状态.
      否则, 即如果收到 No 消息或出现超时, 就中止事务, 向参与者发送 abort 消息.
    2. 参与者如果在规定时间内收到 preCommit 消息, 就可以记录 redo 和 undo 日志,
      并执行对应操作, 然后返回 ack 消息给协调者, 等待 doCommit 消息.
      如果是 abort 消息, 则中止事务.
      如果 Prepared 状态超时, 即没有在规定时间收到 preCommit 消息, 参与者同样中止事务.
  3. doCommit

    1. 协调者如果在规定时间内收到(所有/大多数)参与者的 ack 消息, 就表明可以 commit 事务.
      协调者此时向每个参与者发送 doCommit 消息, 并转移到 commit state.
      否则, 向每个参与者发送 abort 消息.
    2. 参与者如果在规定的时间收到 doCommit/abort 消息, 就 commit/abort 事务, 并返回 ack.
      如果超时, 同样 commit 事务.

在 doCommit 阶段参与者的超时机制基于这样的想法: 此时节点进行到 doCommit 阶段,
那么事务可以 commit 的概率是很大的, 因此没有收到 commit 消息时仍然执行 commit.

3PC 仍然存在问题, 例如, 当发送 preCommit 后, 只有部分参与者收到, 而此时协调者停机.
此时收到 preCommit 消息的节点会在超时后 commit 事务, 而其他参与者则会 abort 事务, 发生了不一致.

CAP

CAP 理论指的是在 Consistency, Availability, Partion 三者中只能满足 CP 或 AP.

  • Consistency: 指的是强一致性. 后面的读一定能读到前面写的内容, 所有读写都满足 linearizability.
  • Availability: 任何非失败节点都应该在有限时间内响应请求.
  • Partion: 允许节点之间丢失任意的消息, 当发生分区时, 不同分区间可能无法通信.

由于分布式系统中无法避免消息丢失, 分区等错误, 因此无法同时满足 CAP. 设想这样的情况:
集群发生分区(A, B), 用户向 A 请求读某个数据, 此时 A 不能确定是否有用户通过 B 更新了该数据.
因此, 如果返回数据, 就不能保证满足一致性(C), 如果不返回数据, 就不能满足可用性(A).

BASE

BASE 是指基本可用(Basically Available), 软状态(Soft state), 最终一致性(Eventual consistency).
是对 CAP 的延伸, 核心思想是即使无法做到强一致性(CAP 中的 C), 但可以实现最终一致性.

  • 基本可用: 系统出现故障时, 不会完全不可用, 核心功能仍然可用. 但是整体性能可能会下降, 功能不完整.
  • 软状态: 系统在中间状态, 此时系统中不同副本间的状态可能会不一致, 但是不会应该整体可用性.
  • 最终一致性: 软状态的持续时间是有限制的, 要保证能系统最终能达到一致状态.

最终一致性分为5种, 可以根据实际情况选择. BASE 的思想就是牺牲强一致性来保证可用性.

Zab

Raft

博客

Paxos

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!