1. 3PC

在2PC基础上进一步改进,提出三阶段提交协议。

3PC(Three-Phase Commit),在2PC的基础上,将准备阶段一分为二,形成由 CanCommit、PreCommit、DoCommit三个阶段组成的事务提交协议。并且在3PC参与者也增加超时机制(2PC只有协调者拥有超时机制),避免了参与者长时间无法与协调者节点通讯(协调者宕机)的情况下,无法释放资源的问题。在参与者超时后,会自动进行本地commit/rollback从而进行释放资源。这种机制也侧面降低了整个事务的阻塞时间和范围。

1.1. 阶段一:CanCommit

CanCommit

  • 事务询问 由协调者向所有参与者发送一个包含事务内容的canCommit请求,询问是否可以执行事务提交操作,并等待参与者响应
  • 反馈询问响应 参与者收到canCommit请求后,根据自身逻辑判断是否可以顺利执行事务,那么反馈yes,否则反馈no。说白了就是检查下自身状态的健康性,看有没有能力进行事务操作。

1.2. 阶段二:PreCommit

在阶段一结果中,如果所有参与者都返回yes,则执行事务预提交,协调者发起PreCommit请求。如果有任何一个参与者节点返回的结果是no,或者协调者在等待参与者节点反馈的过程中超时,整个分布式事务就会中断,协调者就会向所有的参与者发送“abort”请求。

注意:上面所说的参与者增加超时时间,在该阶段就可以派上用场了。在该阶段开始之前,如果协调者宕机,参与者在等待超时时间后,各自选择中断事务,最终达成一致。但是协调者在发出一部分preCommit请求后宕机,有一部分没有收到preCommit请求,那情况则是:一部分参与者执行了preCommit操作,一部分参与者没有执行preCommit操作,最终导致各节点之间数据不一致。

1.2.1. 执行事务预提交

执行事务预提交

  • 发送preCommit请求 由协调者向所有参与者发送preCommit请求,并等待参与者响应
  • 事务预提交 参与者收到preCommit请求后,会执行事务操作,将undo和redo信息写入事务日志中
  • 反馈执行响应 参与者将执行结果反馈给协调者,同时等待最终指令提交(commit)或终止(abort)

1.2.2. 中断事务

该阶段中断事务相比阶段三中断事务要简单,只需要由协调者向所有参与者发送abort请求,通知中断事务。期间参与者在等待协调者的preCommit请求超时后也会主动中断本地事务。

1.3. 阶段三:DoCommit

同样,根据上一阶段的结果,该阶段也会存在两种情况。阶段二所有参与者成功反馈,则执行提交事务请求,否则中断事务。

注意:参与者增加的超时时间,在该阶段也有所体现。在该阶段,无论是协调者宕机了,还是网络原因导致参与者没有收到该阶段的(提交/中断)请求,参与者都会执行本地事务提交。倘若在该阶段,协调者需要发送的是提交事务请求,参与者自动提交本地事务,最后能达到一致性。倘若在该阶段,协调者需要发送的是中断事务请求,如果参与者没有收到该请求,则参与者也会自动提交本地事务,最终导致各节点之间数据不一致。

1.3.1. 提交事务

提交事务

  • 发送提交请求 协调者就会从“预提交状态”变为“提交状态”。然后向所有的参与者节点发送"global_commit"请求
  • 事务提交 参与者收到global_commit请求后,将执行本地事务提交操作,并释放整个事务执行期间占用的事务资源
  • 反馈提交结果 参与者向协调者反馈ack提交结果
  • 完成事务 协调者收到所有参与者的ack消息后,完成事务

1.3.2. 中断事务

  • 发送中断请求 协调者向所有参与者发送abort请求
  • 事务回滚 参与者根据阶段二中记录的undo信息,来执行回滚操作,并释放占用事务资源
  • 反馈回滚结果 参与者向协调者反馈ack回滚结果
  • 中断事务 协调者收到所有参与者的ack消息后,中断事务

1.4. 优缺点

相比于2PC,3PC最大的优点就是减少了参与者的阻塞范围,并且能在协调者故障之后某些情况下继续达成一致。

3PC的缺点,也就是我在每个阶段描述中,注意的那一部分,在某些情况下,3PC必然会造成数据的不一致性。

以上摘自: 分布式一致性协议

results matching ""

    No results matching ""