你可能不知道的平时在用的一致性协议2PC、3PC?

简介: 在分布式系统中,当一个事务操作需要跨越多个分布式节点时,为了保持事务的ACID特性,就出现了“协调者(Coordinator)”来统一调度所有分布式节点的执行逻辑,而被调度的分布式节点则被称为“参与者(Cohort)”。协调者(Coordinator)负责调度参与者(Cohort)的行为,并最终决定这些参与者(Cohort)是否把事务真正进行提交。基于这个思想,衍生出2PC和3PC两种协议。

在分布式系统中,当一个事务操作需要跨越多个分布式节点时,为了保持事务的ACID特性,就出现了“协调者(Coordinator)”来统一调度所有分布式节点的执行逻辑,而被调度的分布式节点则被称为“参与者(Cohort)”。协调者(Coordinator)负责调度参与者(Cohort)的行为,并最终决定这些参与者(Cohort)是否把事务真正进行提交。基于这个思想,衍生出2PC3PC两种协议。


一. 2PC (Two-Phase Commit)


2PC(Two-Phase Commit)为二阶段提交,为了分布式系统下所有节点操作事务能够保存原子性和一致性而设计的一种算法。主要应用在关系型数据库来完成分布式事务处理,利用该协议可以方便地利用协调者(Coordinator)进行统一的事务提交和回滚,从而能够有效的保证分布式数据一致性。


2PC的两阶段


阶段一(提交请求阶段)


各参与者(Cohort)投票表明是否要继续执行接下来的事务提交操作:


  1. 协调者(Coordinator)节点向所有参与者(Cohort)节点询问是否可以执行提交操作,并开始等待各参与者(Cohort)节点的响应。
  2. 参与者(Cohort)节点执行询问发起为止的所有事务操作,并将Undo信息和Redo信息写入日志。
  3. 各参与者(Cohort)节点响应协调者(Coordinator)节点发起的询问。如果参与者(Cohort)节点的事务操作实际执行成功,则它返回一个"同意"消息;如果参与者(Cohort)节点的事务操作实际执行失败,则它返回一个"中止"消息。


阶段二(提交执行阶段)


协调者(Coordinator)会根据参与者(Cohort)的反馈情况来决定是否可以进行事务提交操作,可分为事务提交以及事务中断两种情况 。


事务提交:


当协调者(Coordinator)节点从所有参与者(Cohort)节点获得的对应的消息都为"Yes"时:


  1. 协调者(Coordinator)节点向所有参与者(Cohort)节点发出"Commit"的请求。
  2. 参与者(Cohort)节点收到Commit请求后,正式执行事务操作,并释放在整个事务期间内占用的资源。
  3. 参与者(Cohort)节点向协调者(Coordinator)节点发送"Ack"消息,确认完成。
  4. 协调者(Coordinator)节点收到所有参与者(Cohort)节点反馈的"Ack"完成消息后,完成事务。


21.png


事务中断:


如果任一参与者(Cohort)节点在第一阶段返回的响应消息为"No",或者协调者(Coordinator)节点在第一阶段的询问超时之前无法获取所有参与者(Cohort)节点的响应消息时:


  1. 协调者(Coordinator)节点向所有参与者(Cohort)节点发出"Rollback"请求。
  2. 参与者(Cohort)节点接收到"Rollback"请求,利用之前写入的Undo信息执行回滚,并释放在整个事务期间内占用的资源。
  3. 参与者(Cohort)节点向协调者(Coordinator)节点发送"Ack"回滚完成消息。
  4. 协调者(Coordinator)节点收到所有参与者(Cohort)节点反馈的"Ack"回滚完成消息后,取消事务。


22.png


缺点


  1. 同步阻塞问题:执行过程中,所有参与者(Cohort)节点都是事务阻塞型。各个参与者(Cohort)在等待其他参与者响应的过程中,将无法进行其他任务操作;
  2. 单点故障:由于协调者(Coordinator)的重要性,一旦协调者(Coordinator)发生故障,参与者(Cohort)会一直阻塞下去。特别是在阶段二中,协调者(Coordinator)发生故障,那么所有的参与者(Cohort)还都处于锁定事务资源的状态中,而无法继续完成事务操作。
  3. 数据不一致:在阶段二中,当协调者(Coordinator)向参与者(Cohort)发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者(Coordinator)出现问题,将导致只有一部分参与者(Cohort)收到commit请求,以至于这部分参与者(Cohort)接到commit请求之后就会执行commit操作,而其他部分未接到commit请求的参与者(Cohort)则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。
  4. 不具备完善容错机制:任意一个节点的失败都会导致整个事务的失败。参与者(Cohort)宕机或者超时,都需要协调者(Coordinator)自身机制去判断或者协调者(Coordinator)在发出commit消息之后宕机,而唯一接收到这条消息的参与者(Cohort)同时也宕机了。那么即使协调者(Coordinator)通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。


二. 3PC (Three-Phase Commit)


3PC (Three-Phase Commit)为了改进2PC中出现的同步阻塞、单点问题、脑裂以及保守的容错机制缺陷提出的三阶段提交协议,分为CanCommitPreCommitdoCommit三阶段进行事务处理协议。如下图:


23.png


阶段一:CanCommit


  1. 协调者(Coordinator)节点向所有参与者(Cohort)节点询问是否可以执行提交操作,并开始等待各参与者(Cohort)节点的响应。
  2. 协调者(Coordinator)向参与者(Cohort)发送commit请求,参与者(Cohort)如果可以提交就返回Yes响应进入预备状态,否则返回No响应。


阶段二:PreCommit


协调者(Coordinator)根据参与者(Cohort)的反应情况来决定是否可以继续事务的PreCommit操作。根据响应情况,有以下两种可能执行提交中断事务


执行提交:


协调者(Coordinator)从所有的参与者(Cohort)获得的反馈都是Yes响应,那么就会进行事务的预执行:


  1. 发送预提交请求::协调者(Coordinator)向参与者(Cohort)发送PreCommit请求,并进入Prepared阶段。
  2. 事务预提交:参与者(Cohort)接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。
  3. 响应反馈:如果参与者(Cohort)成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。


中断事务:


有任何一个参与者(Cohort)向协调者(Coordinator)发送了No响应,或者等待超时之后,Coordinator都没有接到参与者(Cohort)的响应,那么就中断事务:


  1. 发送中断请求:协调者(Coordinator)向所有参与者(Cohort)发送abort请求。
  2. 中断事务:参与者(Cohort)收到来自协调者(Coordinator)的abort请求之后(或超时之后,仍未收到参与者(Cohort)的请求),执行事务的中断。


阶段三:DoCommit


该阶段进行真正的事务提交,也可以分为以下两种情况执行提交中断事务:


执行提交


  1. 发送提交请求:协调者(Coordinator)接收到参与者(Cohort)t发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者(Cohort)发送doCommit请求。
  2. 事务提交:参与者(Cohort)接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。
  3. 响应反馈:事务提交完之后,向协调者(Coordinator)发送ACK响应。
  4. 完成事务:协调者(Coordinator)接收到所有参与者(Cohort)的ACK响应之后,完成事务。


中断事务:


协调者(Coordinator)正常,接收到参与者(Cohort)发送的反馈No响应,或者没有收到到Ack响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。


  1. 发送中断请求:协调者(Coordinator)向所有参与者节点发送abort请求;
  2. 事务回滚:参与者(Cohort)接收到abort请求后,利用记录的Undo信息进行事务回滚操作,并在回滚完成后释放整个事务执行期间占用的资源。
  3. 反馈事务回滚结果:参与者(Cohort)在完成事务回滚之后,向协调者(Coordinator)发送Ack消息。
  4. 中断事务:协调者(Coordinator)接收所有参与者(Cohort)的反馈Ack消息后,中断事务。


优缺点


  • 优点: 降低参与者阻塞范围,并能够在出现单点故障后继续达成一致
  • 缺点: 引入preCommit阶段,在这个阶段如果出现网络分区,协调者无法与参与者正常通信,参与者依然会进行事务提交,造成数据不一致。


三. 总结


无论是二阶段提交还是三阶段提交都从不同程度地解决了分布式数据一致性问题,使用范围非常广泛,但都无法彻底解决分布式的一致性问题。还有一种一致性协议Paxos算法,解决了无限期等待问题,也解决了“脑裂”问题,通俗易懂的Paxos原理可查看文章《通俗易懂的Paxos算法-基于消息传递的一致性算法》。


各位看官还可以吗?喜欢的话,动动手指点个💗,点个关注呗!!谢谢支持!



相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
机器学习/深度学习 人工智能 算法
一文让你了解AI产品的测试 评价人工智能算法模型的几个重要指标
一文让你了解AI产品的测试 评价人工智能算法模型的几个重要指标
2198 0
一文让你了解AI产品的测试 评价人工智能算法模型的几个重要指标
|
JavaScript 安全 前端开发
介绍DOM Based XSS
【8月更文挑战第25天】介绍DOM Based XSS
573 1
|
Kubernetes Cloud Native Java
灰度发布、蓝绿部署、金丝雀都是啥?
在滚动部署中,应用的新版本逐步替换旧版本。实际的部署发生在一段时间内。在此期间,新旧版本会共存,而不会影响功能和用户体验。这个过程可以更轻易的回滚和旧组件不兼容的任何新组件。
灰度发布、蓝绿部署、金丝雀都是啥?
|
存储 NoSQL 关系型数据库
面试官:别告诉我你管这个叫高可用
大家好。今天分享一篇写得很透彻的关于高可用的理解。以下是正文: 今天我们来聊一下互联网三高(高并发、高性能、高可用)中的高可用,看完本文相信能解开你关于高可用设计的大部分困惑
|
SQL 存储 分布式计算
【Hive】Hive优化有哪些?
【4月更文挑战第16天】【Hive】Hive优化有哪些?
|
SQL 存储 容灾
关于主从延迟,一篇文章给你讲明白了!
在实际的生产环境中,由单台MySQL作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面 因此,一般来说都是通过集群主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy)来提升数据库的并发负载能力进行部署与实施总结MySQL主从集群带来的作用是:提高数据库负载能力,主库执行读写任务(增删改),备库仅做查询。提高系统读写性能、可扩展性和高可用性。数据备份与容灾,备库在异地,主库不存在了,备库可以立即接管,无须恢复时间。用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。可以简单理解为记录的就是sq
2708 0
|
SQL 分布式计算 资源调度
一文解析 ODPS SQL 任务优化方法原理
本文重点尝试从ODPS SQL的逻辑执行计划和Logview中的执行计划出发,分析日常数据研发过程中各种优化方法背后的原理,覆盖了部分调优方法的分析,从知道怎么优化,到为什么这样优化,以及还能怎样优化。
105073 1
|
Java 应用服务中间件 Apache
|
存储 安全 大数据
DDD到底解决了什么问题
DDD作为架构设计思想帮助微服务控制规模复杂度,那它是怎么做到的呢?
22124 1
DDD到底解决了什么问题
|
存储 关系型数据库 大数据
对比MySQL,一文看透HBase的能力及使用场景
MySQL + HBase 是我们日常应用中常用的两个数据库,分别解决应用的在线事务问题和大数据场景的海量存储问题。 本文内容适合初次理解HBase的读者,包括技术、功能及场景,也欢迎老司机们补充和温故。 更多内容,请查看PPT
10217 122