浅谈分布式系统一致性之3PC协议

可以看到3PC协议中参与者不再过度依赖协调者的指令信号,而是有了自己的相对独立性,可以根据当前所处的状态来进行自我决策。

避免了2PC中的阻塞等待带来的资源浪费情况,确实是个不错的优化, 但是我们并不能完全保证这种优化就都是完全正确的呀

换句话说 3PC解决了2PC的bug,但是不代表3PC没有引入新的bug

五. 3PC协议的一些分析

前面我们说到3PC协议的一个重要作用就是要对2PC协议的改进和优化,从上面的过程分析可知确实做了一些优化,但是仍然不可避免出现了新的问题。

5.1 3PC的数据不一致问题

2PC协议在某些场景下数据不一致问题,那么3PC有没有这种问题呢?

答案是有,根源是新加的参与者超时机制。

比如参与者A因为自身网络问题,在设定时间内未收到协调者的信号,这时参与者A基于之前的状态执行了Commit操作,提交了事务,这种情况确实会发生,根据真实的协调者信号是commit还是rollback会出现不同的结果。

如果协调者发送的是Commit指令,就和参与者A独自决策结果一致,没啥问题。

如果协调者在DoCommit阶段发送的是rollback指令,那么超时的参与者A由于执行了本地事务提交,从而和其他收到指令执行rollback的参与者的数据不一致。

5.2 决策状态的对齐

我们知道 2PC协议的 决策结果初始阶段只有决策者知道 ,只有在它发送了决策解决才有参与者知道,这样就存在决策结果丢失的情况。

假如协调者挂掉,新协调者可以咨询所有的参与者来确定决策状态,根据所有参与者的情况来确定,但是万一真理掌握在少数人手中呢?

极端情况:

假如有10个参与者,9个都是正常的,1个状态未知(先叫做A吧),10个参与者都向协调者发送了反馈,如果A反馈的是Not Ready信号,其他9个都是Ready信号。

协调者汇总结果决策出不具备执行条件,开始向所有参与者发送rollback,恰好第一个收到信号的是A机器,协调者挂了,A收到信号后也挂了。

新的协调者询问了其余9个都是OK,新的协调者就认为具备条件了从而发送Commit信号,这样就出现了不一致。

脑洞大开:

这个过程和清宫剧中皇帝立储很像嘛,皇帝把结果挂在朝堂的牌匾之上,假定诏书消失了且皇帝挂了,那么结果就不得而知了,智囊团在没有私心的前提下就需要考察所有的侯选人的情况来确定,这样就可能出现不一致。

决策透明化:

在3PC中仍然存在只有1台机器收到指令然后挂掉的情况,但是如果出现在前置阶段,对整个结果是没有影响的,因为会被取消并且参与者并没有本地执行。

现在看3PC的思想是把做重大动作时的决策结果透明化统一化,产生的影响也就非常小了,因此PreCommit阶段的状态是明确的。

我们需要把决策结果透明化,让所有参与者都知道决策结果,3PC的PreCommit阶段对齐了结果,只要有1台还活着,整个事务的状态就是确定的,毕竟所有参与者全挂的情况概率非常低。

六.小结

3PC协议是对2PC协议的优化和改进,通过将2PC的准备阶段一分为二:CanCommit和PreCommit, 整个过程中下一阶段的流转要取决于上一个阶段的结果 ,流转简图:

经过CanCommit和PreCommit阶段后,参与者之间对齐并保留了决策结果,避免2PC协议极端情况决策结果的错误缺失,是个比较好的做法。

2PC协议只有协调者有超时机制,3PC协议对参与者也引入了超时机制,在不同的阶段进行不同的超时处理,但是 由于网络波动和网络分区存在让参与者的超时处理带来新的不确定性,甚至可能出现数据不一致

3PC协议增加一轮询问阶段所以整个交互过程比2PC更长了,性能相比2PC是会有一些下降的,但是3PC协议对于网络分区等情况也并没有处理地很好。

总体来说, 3PC相比2PC做了很多改进有一定的效果,但是仍然存在数据不一致问题,还需继续努力