背景介绍
最近大家都相比遇到了就业瓶颈了,很多公司要不就是不招人了,要不就是把门槛抬的很高,所以针对于一些分布式角度而言的技术知识点,更是必备条件以及重中之重了。那么今天笔者就针对于分布式协议以及一些算法原理进行详细的分析和原理介绍。
分布式体系
分布式体系管理的主要内容是面对于分布式节点进行执行事务的操作流程。
整个分布式体系主要包含了几个要素:
- 分布式节点
- 本地操作
- 分布式组合操作
如何可以将分布式节点的每个本地操作达成整齐划一,并且实现统一化的数据状态管理,这将是分布式协议 的重点管理目标和方向。
执行失败状态将会不一致
但是如果一旦出现了其中某一个节点的本地执行出现错误,如下图所示。
就会出现很严重的问题,导致分布式节点的执行不完整,最终造成了数据状态不一致的问题。
分布式协议(2PC+3PC)
每一个分布式节点明确的知道自己执行的事务结果是成功还是失败,但无法知道其他节点的执行结果, 因此为了保持事务的ACI特性, 需要引入一个“协调者”(Coordinator)来调度所有的分布式节点称为“参与者”(Participant) 。基于这种思想衍生出了二阶提交与三阶提交两种协议。
二阶提交(Two-Phase Commit,2PC)
概念介绍
使基于分布式架构下的所有节点在进行事务处理过程中保持原子性与一致性而设计的一种算法。
执行流程
- 阶段一:提交事务请求
- 阶段二:执行事务提交
阶段一:提交事务请求
- 事务询问:协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各个参与者响应。
- 执行事务:各参与者节点执行事务操作, 并将undo与redo信息写入事务日志中。
- 各参与者向协调者反馈事务询问的响应如果参与者成功执行了事务, 就返回YES,如果不成功,就返回NO。
该阶段相当于各个参与者对协调者发送的事务内容进行是否可以执行的投票。
阶段二:执行事务提交
根据参与者的响应,正常情况下有两种情况:
- 成功:YES
- 失败:NO
执行事务提交(响应都为YES)
- 发送提交请求
- 事务提交,协调者向所有参与者节点发出Commit请求,参与者接收到Commit请求后,会正式执行事务提交操作,并在完成后释放事务,执行期间占用的资源
- 反馈事务提交结果,参与者完成事务提交以后,向协调者发送Ack消息
- 完成事务,收到所有参与者节点的Ack消息后,完成事务
中断事务(响应有NO,或有超时)
- 发送回滚请求,协调者向所有参与者节点发出Rollback请求
- 事务回滚,参与者接收到Rollback请求后,会根据undo信息执行执行事务回滚操作,并在完成后释放事务执行期间占用的资源。
- 反馈事务回滚结果,参与者完成事务回滚以后,向协调者发送Ack消息。
- 中断事务,收到所有参与者节点的Ack消息后,完成事务中断
优点
- 原理简单
- 实现方便
缺点
同步阻塞(性能较差)
在二段提交过程中,所有参与该事务操作的逻辑都处于阻塞状态,也就是各个参与者在等待其他参与者响应的过程中都无法执行其他操作。
单点问题(容易造成崩溃)
协调者的角色在整个二段提交协议中起到了非常重要的作用,如果协调者出现问题,参与者将锁定事务资源无法继续完成事务操作。
数据不一致(在二阶段的问题)
在阶段二过程中, 有可能因为网络等原因出现只有部分参与者收到了Commit请求。而出现各个节点数据不一致的问题。
从太过保守
没有容错机制,任何一个节点的失败都会导致整个事务的中断。
三阶提交(Three-Phase Commit,3PC)
概述
2PC的改进版本,将2PC二阶段提交的过程一分为二, 形成了Can Commit, Pre Commit, Do Commit三个阶段组成的事务协议。
Can Commit阶段
1. 事务询问
事务协调者向所有的分布式节点发送一个包含事务内容的can Commit请求, 询问是否可以执行事务提交操作,并开始等待各个参与者响应。
2.各参与者向协调者反馈事务询问的响应
如果参与者认为可以顺利执行事务, 就反馈YES, 并进入预备状态, 否则反馈NO
该阶段相当于各个参与者对协调者发送的事务内容进行是否可以执行的投票
Pre Commit阶段
根据参与者的响应,正常情况下有两种情况:
1. 执行事务提交(响应都为YES)
- 发送预提交请求,协调者向所有参与者节点发出pre Commit请求, 并进入prepared阶段
- 预事务提交,参与者接收到Pre Commit请求后, 会执行事务, 并将undo与redo信息写入事务日志中
- 反馈事务提交结果,参与者完成事务提交以后, 向协调者发送Ack消息, 等待最终的指令:提交(Commit)或终止(abort)
2. 中断事务(响应存在NO,或有超时)
- 发送回滚,请求协调者向所有参与者节点发出abort请求
- 中断事务,收到所有参与者节点的Ack消息后, 或者等待协调者响应超时, 都会中断事务
Do Commit阶段
根据参与者的响应,正常情况下有两种情况:
执行提交(响应都为YES)
- 发送提交请求,协调者向所有参与者节点发出do Commit请求
- 事务提交,参与者接收到do Commit请求后, 会正式执行事务, 并在完成后释放事务执行期间占用的资源
- 反馈事务提交结果,参与者完成事务提交以后, 向协调者发送Ack消息
- 完成事务,收到所有参与者节点的Ack消息后, 完成事务
中断事务(二阶段提交后,参与者响应有NO, 或有超时)
- 发送回滚请求,协调者向所有参与者节点发出abort请求
- 事务回滚,参与者接收到abort请求后, 会根据undo信息执行事务回滚操作, 并在完成后释放事务执行期间占用的资源
- 反馈事务回滚结果,参与者完成事务回滚以后, 向协调者发送Ack消息
- 中断事务,收到所有参与者节点的Ack消息后, 或者等待协调者响应超时, 都会中断事务
优点
降低了二阶段提交的阻塞范围。
缺点
- 参与者收到pre Commit消息后, 一旦无法与协调者通信, 将在超时后提交事务, 在这种情况下,可能会出现数据的不一致性
- 协调者出现故障,协调者与参与者之间的网络出现故障(旦参与者接收不到协调者的请求超时以后,都会进行事务提交)
敬请期待: 【分布式技术专题】「分布式技术架构」一文带你厘清分布式事务协议及分布式一致性协议的算法原理和核心流程机制(下篇)