从2PC和容错共识算法讨论zookeeper中的Create请求 | 京东云技术团队

news2024/11/6 9:47:23

最近在读《数据密集型应用系统设计》,其中谈到了zookeeper对容错共识算法的应用。这让我想到之前参考的zookeeper学习资料中,误将容错共识算法写成了2PC(两阶段提交协议),所以准备以此文对共识算法和2PC做梳理和区分,也希望它能帮助像我一样对这两者有误解的同学。

1. 2PC(两阶段提交协议)

两阶段提交 (two-phase commit) 协议是一种用于实现 跨多个节点的原子事务(分布式事务)提交 的算法。它能确保所有节点提交或所有节点中止,并在某些数据库内部使用,也以 XA事务 的形式在分布式服务中使用。

在 Java EE 中,XA事务使用 JTA(Java Transaction API) 实现。

2PC的实现

2PC包含 准备阶段 和 提交阶段 两个阶段,需要借助 协调者(事务管理器,如阿里巴巴的Seata)  来实现,参与分布式事务的数据库节点为 参与者。当分布式服务中的节点准备提交时,协调者开始 准备阶段:发送一个 准备请求 到每个节点,询问它们是否能够提交,然后协调者会跟踪参与者的响应

  • 如果所有参与者都回答"是",表示它们已经准备好提交,那么协调者在 提交阶段 发出 提交请求,分布式事务提交
  • 如果任意一个参与者回答"否",则协调者在 提交阶段 中向所有节点发送 中止请求,分布式事务回滚

image.png

上图是2PC提交成功的情况,我们来详述下过程:

  1. 当服务启动一个分布式事务时,它会向协调者请求一个事务ID,此事务ID是全局唯一的
  2. 在每个参与者上启动单节点事务,每个单节点事务会持有这个全局事务 ID。所有的读写都是在这些单节点事务中各自完成的。如果在这个阶段出现任何问题(节点崩溃或请求超时),则协调者或任何参与者都可以中止
  3. 当应用准备提交时,对应准备阶段:协调者向所有参与者发送一个 准备请求,同样也持有全局事务 ID 。如果任意一个请求失败或超时,则协调者向所有参与者发送针对该事务 ID 的 中止请求,即2PC提交中止的情况
  4. 参与者收到 准备请求 时,需要确保在任意情况下都可以提交事务。这包括将所有事务数据写入磁盘(出现故障,电源故障,或硬盘空间不足都不能是稍后拒绝提交的理由)以及检查是否存在任何冲突或违反约束。通过向协调者回答 “是”,节点承诺这个事务一定可以不出差错地提交。也就是说:参与者没有实际提交,同时放弃了中止事务的权利
  5. 当协调者收到所有 准备请求 的答复时,会就 提交或中止事务 作出明确的决定(只有在 所有参与者 投赞成票的情况下才会提交),这里对应提交阶段。协调者必须把这个提交或中止事务的决定 写到磁盘上的事务日志中,记录为 提交点(commit point) 。如果它随后崩溃,能通过提交点进行恢复
  6. 一旦协调者的决定已经保存在事务日志中,提交或中止请求会发送给所有参与者。如果这个请求失败或超时,协调者 必须永远保持重试,直到成功为止,对于已经做出的决定,协调者不管需要多少次重试它都必须被执行

2PC协议中有两个关键的 不归路 需要注意:

  • 一旦协调者做出决定,这一决定是不可撤销的
  • 参与者投票 “是” 时,它承诺它稍后肯定能够提交(尽管协调者可能仍然选择放弃),即使参与者在此期间崩溃,事务也需要在其恢复后提交,而且由于参与者投了赞成,它不能在恢复后拒绝提交

这些承诺保证了2PC的 原子性。

协调者失效的情况

如果 协调者失效 并且所有参与者都收到了准备请求并投了是,那么参与者什么都做不了只能等待,而且这种情况 解决方案 是等待协调者恢复或数据库管理员介入操作来提交或回滚事务,当然如果在生产期间这需要承担运维压力。

所以,协调者在向参与者发送提交或中止请求 之前,将其提交或中止决定写入磁盘上的事务日志(提交点)。这样就能在协调者发生崩溃恢复后,通过读取其事务日志来确定所有 存疑事务 的状态,任何在协调者事务日志中没有提交记录的事务都会被终止。因此两阶段提交在第二阶段(提交阶段)存在阻塞等待协调者恢复的情况,所以两阶段提交又被称为 阻塞原子提交协议

番外:3PC

三阶段提交协议也是应用在分布式事务提交中的算法,它的提出是为了解决两阶段提交协议中存在的阻塞问题。它分为 CanCommit阶段PreCommit阶段 和 DoCommit阶段,通过引入 参与者超时判断机制 来解决2PC中存在的参与者依赖协调者的提交请求而阻塞导致的资源占用等问题。

上图为在DoCommit阶段,参与者判断 DoCommit请求 超时情况的流程图,我们详述下它的避免阻塞的流程

  1. 服务在每个参与者上启动单节点事务,当参与者准备提交时,对应CanCommit阶段,协调者会向所有参与者发送 CanCommit请求,如果任意一个请求失败或超时,则协调者会向所有参与者发送针对该事务的 中止请求,执行事务回滚
  2. 当协调者收到所有CanCommit请求的答复时,如果全是“是”那么则进入PreCommit阶段,否则发送中止请求,执行事务回滚
  3. 进入PreCommit阶段后,协调者会向所有参与者发送 PreCommit请求,同样还是如果存在请求失败或超时,会发送中止请求执行事务回滚
  4. 协调者收到所有PreCommit请求的答复时,如果全是“是”那么则进入DoCommit阶段,否则发送中止请求,执行事务回滚
  5. 进入DoCommit阶段后,协调者会向所有参与者发送 DoCommit请求,注意这里,如果某个参与者没有收到该请求,它默认认为协调者会发送提交请求,那么便本地执行提交事务,从而避免阻塞

3PC虽然解决了2PC中存在的阻塞问题,但是也引入了新的问题:

  • 如果协调者在DoCommit阶段回复的是中止请求,那么超时节点自顾自地提交事务就会发生数据不一致的情况
  • 通讯次数增加和实现相对复杂

3PC使原子提交协议变成非阻塞的,但是3PC 假定网络延迟和节点响应时间有限,在大多数具有无限网络延迟和进程暂停的实际系统中,它 并不能保证原子性。非阻塞原子提交需要一个 完美的故障检测器 来以可靠的机制判断一个节点是否已经崩溃,而在无限延迟的网络中,超时并不是一种可靠的故障检测机制,因为即使节点没有崩溃也会因为网络延迟而超时,出于这个原因,2PC仍然被使用,尽管存在协调者故障的问题。

2. 容错共识算法

容错共识算法用于 节点间数据同步,保证各个副本间数据的一致性和集群的高可用。它的通常形式是一个或多个节点可以 提议(propose)  某些值,而共识算法 决定(decides)  采用其中的某个值,并让这些节点就提议达成一致。共识算法必须具备如下性质:

  • 一致同意:没有两个节点的决定不同
  • 完整性:没有节点决定两次
  • 有效性:如果节点决定了v值,那么v由该节点所提议
  • 终止性:由所有未崩溃的节点来最终决定值

终止性实质上是说:容错共识算法不能简单地永远闲坐着等待,而是需要根据大多数节点来达成一项决定,因此终止属性也暗含着 不超过一半的节点崩溃或不可达 的信息。

一致同意和完整性是共识的 核心思想,即所有节点决定了相同的结果并且决定后不能改变主意。

容错共识算法在节点集群内部都以某种形式使用一个领导者,并定义了一个 纪元编号(epoch number)  来确保在每个时代中,领导者都是唯一的。每当现任领导宕机时,节点间会开始一场投票,来选出一个新的领导,每次选举被赋予一个新的纪元编号(全序且单调递增),如果有两个不同时代的领导者之间出现冲突(脑裂问题),那么带有更高纪元编号的领导者说了算。领导者每想要做出的每一个决定,都必须将提议值发送给其他节点,并等待 法定人数 的节点响应并赞成提案。法定人数通常(但不总是)由多数节点组成(一般为过半),只有在没有发现任何带有更高纪元编号的领导者的情况下,一个节点才会投票赞成提议。

容错共识算法的局限性

  1. 节点在做出决定之前对提议进行投票的过程是一种同步复制
  2. 共识系统总是需要有 法定人数 的节点存活来保证运转
  3. 大多数共识算法假定参与投票的节点是固定的集合,这意味着你不能简单的在集群中添加或删除节点
  4. 共识系统通常依靠 超时 来检测失效的节点,在网络延迟高度变化的环境中,特别是在地理上散布的系统,经常发生一个节点由于暂时的网络问题,错误地认为领导者已经失效。虽然这种错误不会损害安全属性,但频繁的领导者选举会导致糟糕的性能表现,所以共识算法对网络问题比较敏感,而在面对不可靠的网络相关的共识算法研究仍在进展中

3. 2PC和容错共识算法的区别

  1. 负责解决的问题不同:2PC解决的是分布式事务的一致性,各个节点存储的数据各有不同,目标侧重于保证事务的ACID;容错共识算法解决的是节点副本间数据的一致性和保证集群的高可用,节点间存储的数据完全一致,目标侧重于数据的复制和同步
  2. 每个提议通过要求的参与节点数不同:2PC要求 所有的参与者表决成功 才通过;容错共识算法只需要 遵循基于法定人数的表决 即可,这也是容错共识算法 终止属性(由所有未崩溃的节点来决定最终值)  的体现
  3. 集群的高可用保证:2PC的协调者不是通过选举产生的,而是单独部署并人为指定的组件,所以它没有选主机制,不具备高可用性;应用容错共识算法的集群领导者是通过选举机制来指定的,并且在发生异常情况时(主节点宕机)能够选出新的领导者,并进入一致的状态,以此来保证集群的高可用

4. zookeeper中的一次Create请求

一些资料中会提到zookeeper在执行CRUD请求时,使用的是2PC,而 实际上它使用的是容错共识算法。我们以Create请求的流程为例(如下图),来加深和记忆这一知识

  1. 客户端发 create 请求到 Leader,即使请求没落到 Leader 上,那么其他节点也会将写请求转发到 Leader
  2. Leader 会先发一个 提议(proposal)请求给各个 Follower,且自己将数据写到本地文件
  3. Follower 集群收到 proposal 请求后会将数据写到本地文件,写成功后返回给 Leader 一个 ack回复
  4. Leader 发现收到 ack 回复的数量为 法定人数(过半,包含当前 Leader 节点)时,则提交一个 commit 请求给各个 Follower 节点。发送 commit 请求就代表该数据在集群内同步情况没有问题,并且 可以对外提供访问 了,此时Leader会把数据写到内存中
  5. Follower 收到 commit 请求后也会将数据写到各自节点的内存中,同时Leader会将数据发给 Observer集群,通知 Observer集群 将数据写到内存

巨人的肩膀

  • 《数据密集型应用系统设计》第九章:分布式事务与共识
  • 百度百科:三阶段提交
  • 浅谈分布式一致性协议之3PC
  • 分布式事务(2PC) vs 共识协议(Paxos/raft)
  • 《深度剖析zookeeper核心原理》
  • 原文收录:GitHub-Enthusiasm

作者:京东物流 王奕龙

内容来源:京东云开发者社区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/686914.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

近日网上传出消息,ARM正与Intel共同开发制造芯片

近日网上传出消息,ARM正与Intel共同开发制造芯片,让芯片设计者能够基于Intel 18A制程打造低功耗的SoC。另有多位业内人士透露,这次制造的芯片将主要用于移动设备、笔记本电脑、数据中心等。 若这一消息属实,会对中国芯片行业带来…

常见的SQL优化方案

1. insert优化 1.1 批量插入 我们之前插入数据都是一条一条插入的,会导致频繁操作数据库,从而影响性能。比如遍历某个集合,然后逐个使用insert语句插入数据库表中 INSERT INTO table (name, age) VALUES (张三, 18); INSERT INTO table (na…

6-js基础-3

JavaScript 基础 - 3 知道什么是数组及其应用的场景,掌握数组声明及访问的语法,具备利用数组渲染柱形图表的能力 今日重点: 循环嵌套数组综合案例 今日单词: 循环嵌套 利用循环的知识来对比一个简单的天文知识,我们…

arcpy制作脚本工具相关(制作并添加脚本工具、脚本工具消息提示、arcpy工具自动获取数据)

前言 采用arcpy制作arcgis的脚本工具,记录如下。 一、脚本工具的制作 制作脚本工具分为两步: 1、先编写对应功能的python脚步 2、将对应功能的脚本修改为,能自己手动选择输入输出数据的脚本 3、将修改完的脚本添加到工具箱 1、编写代码 我…

618种草观察丨益生菌「蓝」在一起,酸奶「地域控」?

2023年的“618”,食饮行业中,种草战线格外热闹,品牌花式“开屏”,吸引消费者。 数说故事发布「SMI社媒心智品牌榜」,本期持续关注健康食品,也新增了今夏网红酸奶行业,一起看看这两大赛道中&…

使用power rail连接secondary pg pin的方法

过往文章: secondary pg pin的作用与连接 之前写到过secondary pg pin的种类与几种连接方式,其中使用最多的方法是NDR rule + route_group的方式,这样工作量少,不容易出错,但也有弊端,那就是一…

ctfshow web入门 内网渗透篇

web859 首先ssh连接上之后传个fscan上去,扫描下内网靶机 发现.5和.6的比较可疑。 一个存在web服务,一个存在445端口。 先看下445端口,靶机给我们提供了msf,所以直接用msf打下Samba msfconsole use exploit/linux/samba/is_kno…

数字贸易下转口贸易企业如何高效管理?

什么是转口贸易?是指企业在国内购买进口货物,经过加工、组装、包装等方式改变其性质,再出口到海外市场的贸易活动。这种贸易方式对于促进国际贸易和提高企业竞争力都有着非常重要的作用,但同时也存在着一些风险和难点,…

如何向领导建议数字化转型应着手数据治理?_光点科技

在当今数字化时代,企业的数字化转型已经成为一个迫切的任务。然而,数字化转型不仅仅涉及技术的引入,更需要在数据治理方面进行全面的改进。 一、数据治理是数字化转型的基石。 数据是企业最重要的资产之一,通过对数据的管理和利用…

电气工程师日常工作常遇到的41种接线方法(二)

021 缘耐压测试仪线路 这种绝缘耐压测试仪可测灯具,将待测灯具与A、B两接线柱接好,按下按钮SB1,中间继电器KA1得电并自锁;然后将调压器VT(1∶10,输出0~250V)调至需测的电压值,如需调到1500V则将VT调到电压…

第四章.­ ­ Feasibility of Learning

第四章. Feasibility of Learning 本章主要介绍机器学习的可行性,讨论问题是否可以使用机器学习来解决。 4.1 Learning is Impossible 1.示例描述 1).九宫格样本类型的预测描述: 图中有6个样本,分成两个类别(1和-1&#xff09…

pytorch搭建VGG网络

pytorch搭建VGG网络 CNN 感受野VGG-16搭建VGG网络model.pytrain.pypredict.py VGG 网络的创新点:通过堆叠多个小卷积核来替代大尺度卷积核,可以减少训练参数,同时能保证相同的感受野。 例如,可以通过堆叠两个 33 的卷积核替代 5x5…

SpringSecurity6.0+Redis+JWT基于token认证功能开发(可用于实际生产项目,保证API安全)

基于token认证功能开发 引子:最近做项目时遇到了一个特殊的需求,需要写共享接口把本系统的一些业务数据共享给各地市的自建系统,为了体现公司的专业性以及考虑到程序的扩展性(通过各地市的行政区划代码做限制)&#xf…

Java框架之spring AOP 和 IOC

写在前面 本文一起看下spring aop 和 IOC相关的内容。 1:spring bean核心原理 1.1:spring bean的生命周期 spring bean生命周期,参考下图: 我们来一步步的看下。 1 其中1构造函数就是执行类的构造函数完成对象的创建&#x…

第八十四天学习记录:Linux基础:初识Linux

流行的Linux发行版: 任何人都可以封装Linux,目前市面上有非常多的Linux发行版,常用的知名的如下: VMware WorkStations安装 安装完成后,要通过下图方式查看网络适配器是否正常配置: 配置成功&#xff1a…

软件需求分析文档怎么写?

什么是软件需求规范文档 (SRS)? 软件需求规范 (SRS) 文档列出了未来项目的需求、期望、设计和标准。其中包括规定项目目标的高级业务需求、最终用户要求和需求以及产品在技术方面的功能。简而言之,SRS 提供…

Vue-Element-Admin项目学习笔记(8)配置表单校验规则

前情回顾: vue-element-admin项目学习笔记(1)安装、配置、启动项目 vue-element-admin项目学习笔记(2)main.js 文件分析 vue-element-admin项目学习笔记(3)路由分析一:静态路由 vue-element-adm…

软考:中级软件设计师:校验码,汉明码纠错,信息位L和校验位r的关系

软考:中级软件设计师:校验码,汉明码纠错 提示:系列被面试官问的问题,我自己当时不会,所以下来自己复盘一下,认真学习和总结,以应对未来更多的可能性 关于互联网大厂的笔试面试,都是…

Linux通过crontab定时执行脚本任务

Linux通过crontab定时执行脚本任务 前言1. 创建写入脚本2. 设置执行权限3. 添加定时任务定时任务语法格式每分钟写入一条信息到指定文件 4. 查看日志文件5. 定时执行脚本的作用和用途 前言 在Linux中可以使用crontab来定时执行脚本。crontab是一个用于管理定时任务的工具&…

我这样回答多线程并发,面试官直接惊叹!

目录 前言: 1.单线程执行 2、多线程执行 3.守护线程 4.阻塞线程 前言: 多线程并发是一种处理任务的方式,它可以在同一时间内执行多个任务。多线程并发通常应用于需要同时处理多个任务或同时运行多个程序的情况下。 1.单线程执行 Pyth…