分布式系统 - 一致性,事务提交

一致性分类

  • 强一致性(strong)
  • 单调一致性(monotonic)
  • 会话一致性 (session)
  • 最终一致性(eventual)
  • 弱一致性(weak)

一致性算法

一致性协议

参考文章:

  1. 分布式系统的事务处理 https://coolshell.cn/articles/10910.html

二阶段提交

绝大部分的关系型数据库都是采用二阶段提交协议来完成分布式事务的处理。

提交过程:

  • 投票

    • 两将军问题:
        1. 协调者向各个节点发送提交事务的消息
        1. 各节点接收到消息后开始执行事务但不提交,同时记录Redo、Undo日志
        1. 各节点执行完成事务后向协调者反馈执行结果
  • 执行

    • 协调者根据各个节点反馈的情况来决定是否进行事务提交
    • 提交事务
        1. 向各节点发送提交请求
        1. 节点开始提交事务
        • 执行事务提交,并在完成后释放期间所占用的资源
        1. 反馈事务提交结果
        • 向协调者发送ack消息
            1. 全部响应Yes
            1. 部分响应No
          • 原因
            • 执行业务的事务失败
            • 网络超时
        1. 完成事务
        • 协调者接收到到所有参与者反馈后完成事务
    • 回滚事务
        1. 发送回滚请求
        1. 利用Undo信息回滚事务
        1. 反馈事务结果
        1. 完成终端机事务
  • 优点

    • 原理简单,实现方便
  • 缺点

    • 同步阻塞
    • 单点问题
      • 协调者在整个阶段中起到非常重要的作用,一旦协调者出现问题那整个提交流程将无法运转,如果是在第二个阶段中出现问题,那么其他参与者将一直处于锁定资源状态,而无法完成其他事务操作。
    • 数据不一致
    • 过于保守

三阶段提交

三阶段提交即将二阶段提交协议中的第一步投票阶段拆分为两个阶段:

  1. 先询问 2. 再锁定资源。

所以三阶段的核心理念是: 在询问的时候并不锁定资源,除非所有人都同意了,才开始锁资源

  • 提交过程

    • CanCommit 这期间只询问而不执行事务,也就不会锁定资源

        1. 询问各个节点是否可以执行事务
        1. 各个节点向协调者反馈询问结果
    • PreCommit

      • 执行事务预提交 所有节点都返回yes ,则执行预提交

          - 协调者向各个节点发送预提交请求
          - 各个节点执行事务预提交,并记录Redo Undo 日志
          - 各个节点反馈执行结果
        
      • 中断事务 只要有一个节点反馈no 则中断事务执行

    • doCommit

      • 提交事务

          - 发送提交请求
          - 各个节点提交事务
          - 反馈事务提交结果
          - 完成事务
        
      • 中断事务