热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

分布式系统一致性专题:3PC协议的优化和问题

本文介绍了分布式系统一致性专题中的3PC协议,该协议是对2PC协议的优化和改进。文章详细解释了3PC协议的三个阶段:CanCommit、PreCommit和DoCommit,并分析了每个阶段可能出现的情况和处理方式。同时,文章也指出了3PC协议存在的问题,如参与者超时机制可能导致数据不一致等。总体来说,3PC协议在优化和改进方面取得了一定效果,但仍需继续努力解决数据不一致问题。
导读 分布式系统一致性专题本期该写 3PC 协议了,上周太忙没有时间更新,就拿了之前的旧文章做了一些调整重发了一下,还望各位读者海涵。后面大约还有3期:Paxos 协议、Raft 协议等,先预热一下。

分布式系统一致性专题本期该写 3PC 协议了,上周太忙没有时间更新,就拿了之前的旧文章做了一些调整重发了一下,还望各位读者海涵。后面大约还有3期:Paxos 协议、Raft 协议等,先预热一下。温馨提示:本篇文章并不会枯燥,换了个画图工具,对于我这种建筑专业出身的IT狗来说,画图简直是最开心的事情了,所以放心看吧!

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

图(网络)|猎户座大星云

之前文章中提到了 2PC 协议存在的协调者单点、参与者阻塞超时、网络分区、容错性等问题,这些在某些程度上是做优化和调整的,并不是致命问题。我们对 2PC 协议的异常情况做了拆解,但是那是个m*n的组合问题,我们尽量去分析主要矛盾,于是发现在协调者和唯一接收指令的参与者都出现不可恢复宕机时,即使后面选举了新的协调者,仍然可能出现数据的不一致性。3PC 的出现可能是多种因素促成的。但是基本上可以确定 3PC 将对 2PC 存在的问题进行修正和优化,但是这样并不意味着 3PC 不会引入新的问题。本文将从 3PC 的协议过程来阐述这两大块内容:

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

3PC协议 Three-Phase-Commit 又称三阶段提交协议,相比 2PC 协议增加了一个阶段,因此我们普遍把 3PC 协议看作是 2PC 协议的改进版本。3PC 协议将 2PC 协议的准备阶段一分为二,从而形成了三个阶段:

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

协调者和参与者等待超时情况单独说,先看正常情况的基本过程,要不然容易混淆。

在2PC准备阶段中,协调者向参与者发送指令后,参与者如果具备执行条件,则获取锁并执行动作,只不过未真正提交,可以认为参与者就差临门一脚了,还得等协调者信号。如果是 commit 信号那还好,如果是 rollback 信号,那么对于一些本地执行了动作的参与者来说白白浪费了,所以从这个角度来说,2PC 有点激进了,但是这么做也是有原因的,在复杂的网络环境中多一轮交互意味着性能的损耗。3PC来说更加合理,先由协调者向参与者发送询问信号,兄弟们有档期吗??然后开始收集反馈,相比来说更加轻量。这个阶段参与者并不真实获取锁占用资源,只是对自身执行事务状态的检查,查看是否具备执行事务的条件,进而回复询问。

根据参与者对询问的反馈,在 CanCommit 阶段可能出现的两情况:

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

图:询问阶段所有参与者均具备执行事务条件

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

图:询问阶段存在不具备条件的参与者

第二个阶段的具体动作取决于第一个阶段的结果,因此可以分为两种情况:

在第一阶段所有参与者都 Ready,那么协调者就会向参与者发送本地执行的相关指令,这部分和 2PC 的第一阶段非常相似,参与者收到指令后进行本地事务执行,并记录日志,并且对处理结果反馈到协调者,来做决策。过程中参与者可能成功或者失败,出现了两种情况:

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

图:PreCommit阶段参与者均反馈成功

分布式系统一致性之3PC协议浅谈
图:PreCommit阶段参与者中存在失败实例

在第一阶段如果存在参与者不 Ready 的情况,那么协调者就会发送信号给所有参与者,告知本次事务取消了,该干啥干啥吧,对参与者来说损失并不大,因为本质上参与者并没有做什么事情。

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

这是 3PC 的第三个阶段和2PC的第二个阶段类似,同样的 DoCommit 执行具体动作取决于第二阶段 PreCommit 的结果,因此仍然分为两种情况:

在 PreCommit 之后参与者全部完成本地事务执行但是没有提交,并且都给协调者 ACK 回复,这时协调者认为万事俱备只欠东风了,在 DoCommit 阶段协调者向参与者发送提交指令,参与者收到之后开始执行本地提交,并反馈结果,最终完成这次事务,Cool!

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

协调者在第二个阶段 PreCommit 收到参与者的反馈后,发现存在部分参与者无法执行事务的情况,这时就决定告诉其他参与者本地回滚,释放资源,取消本次事务。

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

我们前面提到 3PC 要解决 2PC 的参与者阻塞超时问题,在2PC中参与者比较痴情,协调者不给信号会长时间阻塞,不释放资源,这样别人也没法处理其他事情,确实不太好,看来 2PC 还是太依赖协调者了。3PC 认为网络超时是普遍发生的情况,如果参与者在一种大概率确定的状态下执行一些动作也是被允许的,将在外军令有所不受。3PC 的超时处理可能发生在 PreCommit 和 DoCommit 阶段,来看个图:

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

协调者和参与者之间可能存在较大的网络延时,或者协调者出现故障,或者出现网络分区等情况,参与者并不会傻等,在超过设定时间之后,参与者就继续做之前的事情了,因为好像被大哥鸽了,只能该干啥干啥,这也是正确的决策。

在 CanCommit 和 PreCommit 之后,参与者认为大家都对齐了都是棒棒的,如果参与者在设定时间内并没有收到协调者的 DoCommit 指令,那么就本地执行提交完成这次事务,因为参与者揣测大哥的意思大概率也是让我们提交,干等着也不是办法,回滚可能和大家不一样,抉择之下参与者选择提交事务。

3PC协调者的等待超时处理和2PC基本上是一样的,无论在哪个阶段超时都认为不具备条件,进行 abort 或者 rollback 操作,这个非常好理解。

可以看到3PC协议中参与者不再过度依赖协调者的指令信号,而是有了自己的相对独立性,可以根据当前所处的状态来进行自我决策。避免了2PC中的阻塞等待带来的资源浪费情况,确实是个不错的优化,但是我们并不能完全保证这种优化就都是完全正确的呀!换句话说3PC解决了2PC的bug,但是不代表3PC没有引入新的bug。

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

2PC协议在某些场景下数据不一致问题,那么3PC有没有这种问题呢?答案是有,根源是新加的参与者超时机制。比如参与者A因为自身网络问题,在设定时间内未收到协调者的信号,这时参与者A基于之前的状态执行了Commit操作,提交了事务,这种情况确实会发生,根据真实的协调者信号是commit还是rollback会出现不同的结果。

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

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

我们知道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协议浅谈

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

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

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

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

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

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


推荐阅读
  • 本文探讨了使用Python实现监控信息收集的方法,涵盖从基础的日志记录到复杂的系统运维解决方案,旨在帮助开发者和运维人员提升工作效率。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • Git版本控制基础解析
    本文探讨了Git作为版本控制工具的基本概念及其重要性,不仅限于代码管理,还包括文件的历史记录与版本切换功能。通过对比Git与SVN,进一步阐述了分布式版本控制系统的独特优势。 ... [详细]
  • 本文详细介绍了MySQL InnoDB存储引擎中的Redo Log和Undo Log,探讨了它们的工作原理、存储方式及其在事务处理中的关键作用。 ... [详细]
  • 本文探讨了MySQL中的死锁现象及其监控方法,并介绍了如何通过配置和SQL语句调整来优化数据库性能。同时,还讲解了慢查询日志的配置与分析技巧。 ... [详细]
  • Awk是一款功能强大的文本分析与处理工具,尤其在数据解析和报告生成方面表现突出。它通过读取由换行符分隔的记录,并按照指定的字段分隔符来划分和处理这些记录,从而实现复杂的数据操作。 ... [详细]
  • ArcBlock 发布 ABT 节点 1.0.31 版本更新
    2020年11月9日,ArcBlock 区块链基础平台发布了 ABT 节点开发平台的1.0.31版本更新,此次更新带来了多项功能增强与性能优化。 ... [详细]
  • Spring Security基础配置详解
    本文详细介绍了Spring Security的基础配置方法,包括如何搭建Maven多模块工程以及具体的安全配置步骤,帮助开发者更好地理解和应用这一强大的安全框架。 ... [详细]
  • Hibernate全自动全映射ORM框架,旨在消除sql,是一个持久层的ORM框架1)、基础概念DAO(DataAccessorOb ... [详细]
  • 在Android应用开发过程中,开发者经常遇到诸如CPU使用率过高、内存泄漏等问题。本文将介绍几种常用的命令及其应用场景,帮助开发者有效定位并解决问题。 ... [详细]
  • 为何Compose与Swarm之后仍有Kubernetes的诞生?
    探讨在已有Compose和Swarm的情况下,Kubernetes是如何以其独特的设计理念和技术优势脱颖而出,成为容器编排领域的领航者。 ... [详细]
  • Docker安全策略与管理
    本文探讨了Docker的安全挑战、核心安全特性及其管理策略,旨在帮助读者深入理解Docker安全机制,并提供实用的安全管理建议。 ... [详细]
  • 使用TabActivity实现Android顶部选项卡功能
    本文介绍如何通过继承TabActivity来创建Android应用中的顶部选项卡。通过简单的步骤,您可以轻松地添加多个选项卡,并实现基本的界面切换功能。 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
author-avatar
纯洁的老宁同志
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有