分布式理论系列(二)一致性算法:2PC 到 3PC 到 Paxos 到 Raft 到 Zab
分布式理论系列(二)一致性算法:2PC 到 3PC 到 Paxos 到 Raft 到 Zab
本文介绍一致性算法: 2PC 到 3PC 到 Paxos 到 Raft 到 Zab
两类一致性算法(操作原子性与副本一致性)
2PC 3PC
协议用于保证属于多个数据分片上的操作的原子性。这些数据分片可能分布在不同的服务器上,2PC 协议保证多台服务器上的操作要么全部成功,要么全部失败。Paxos Raft Zab
协议用于保证同一个数据分片的多个副本之间的数据一致性。当这些副本分布到不同的数据中心时,这个需求尤其强烈。
一、2PC(阻塞、数据不一致问题、单点问题)
Two-Phase Commit(两阶段提交) 是计算机网络尤其是在数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务处理过程中能够保持原子性和致性而设计的一种算法。通常,二阶段提交协议也被认为是一种一致性协议,用来保证分布式系统数据的一致性。绝大部分的关系型数据库都是采用二阶段提交协议来完成分布式事务处理。
1.1 协议介绍
第一阶段:提交事务请求(投票阶段)
事务询问
协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。
执行事务
各参与者节点执行事务操作,并将 Undo 和 Redo 信息计入事务日志中。
各参与者向协调者反馈事务询问的响应
如果参与者成功执行了事务操作,那么就反馈给协调者 Yes 响应,表示事务可以执行;如果参与者没有成功执行事务,那么就反馈给协调者 No 响应,表示事务不可以执行。
第二阶段:执行事务提交(执行阶段)
(1)执行事务提交
如果所有参与者的反馈都是 Yes 响应,那么
发送提交请求
协调者向所有参与者节点发出Commit请求
事务提交
参与者接收到Commit请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源
反馈事务提交结果
参与者在完成事务提交之后,向协调者发送ACK信息
完成事务
协调者接收到所有参与者反馈的ACK消息后,完成事务
(2)中断事务
任何一个参与者反馈了 No 响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应,那么就会中断事务。
发送回滚请求
协调者向所有参与者节点发出Rollback请求
事务回滚
参与者接收到rollback请求后,会利用其在阶段一中记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放整个事务执行期间占用的资源
反馈事务回滚结果
参与者在完成事务回滚之后,向协调者发送ACK信息
中断事务
协调者接收到所有参与者反馈的ACK信息后,完成事务中断
1.2 优缺点
优点:原理简单、实现方便
缺点:同步阻塞、单点问题、数据不一致、太过保守
(1)同步阻塞
同步阻塞会极大地限制分布式系统的性能。在二阶段提交的执行过程中,所有参与该事务操作的逻辑都处于阻塞状态,各个参与者在等待其他参与者响应的过程中,将无法进行其他任何操作。
(2)单点问题
一旦协调者出现问题,那么整个二阶段提交流程将无法运转,更为严重的是,如果是在阶段二中出现问题,那么其他参与者将会一直处于锁定事务资源的状态中,无法继续完成事务操作。
(3)数据不一致
在阶段二,当协调者向所有参与者发送commit请求之后,发生了局部网络异常或协调者在尚未发完commit请求之前自身发生了崩溃,导致最终只有部分参与者接收到了commit请求,于是这部分参与者执行事务提交,而没收到commit请求的参与者则无法进行事务提交,于是整个分布式系统出现了数据不一致性现象。
(4)太过保守
如果参与者在与协调者通信期间出现故障,协调者只能靠超时机制来判断是否需要中断事务,这个策略比较保守,需要更为完善的容错机制,任意一个节点的失败都会导致整个事务的失败。
二、3PC(解决2PC的阻塞,但还是可能造成数据不一致)
Three-Phase Commit,三阶段提交,分为 CanCommit、PreCommit、doCommit 三个阶段。
2.1 协议介绍
为了避免在通知所有参与者提交事务时,其中一个参与者 crash 不一致时,就出现了三阶段提交的方式。三阶段提交在两阶段提交的基础上增加了一个 preCommit 的过程,当所有参与者收到 preCommit 后,并不执行动作,直到收到 commit 或超过一定时间后才完成操作。
第一阶段: CanCommit
事务询问
协调者向各参与者发送 CanCommit 的请求,询问是否可以执行事务提交操作,并开始等待各参与者的响应参与者向协调者反馈询问的响应
参与者收到 CanCommit 请求后,正常情况下,如果自身认为可以顺利执行事务,那么会反馈 Yes 响应,并进入预备状态,否则反馈 No。
第二阶段: PreCommit
(1)执行事务预提交
如果协调者接收到各参与者反馈都是 Yes,那么执行事务预提交
发送预提交请求
协调者向各参与者发送 preCommit 请求,并进入 prepared 阶段事务预提交
参与者接收到 preCommit 请求后,会执行事务操作,并将Undo和Redo信息记录到事务日记中各参与者向协调者反馈事务执行的响应
如果各参与者都成功执行了事务操作,那么反馈给协调者 Ack 响应,同时等待最终指令,提交 commit 或者终止 abort
(2)中断事务
如果任何一个参与者向协调者反馈了No响应,或者在等待超时后,协调者无法接收到所有参与者的反馈,那么就会中断事务。
发送中断请求
协调者向所有参与者发送 abort 请求中断事务
无论是收到来自协调者的 abort 请求,还是等待超时,参与者都中断事务
第三阶段: doCommit
(1)执行提交
发送提交请求
假设协调者正常工作,接收到了所有参与者的ack响应,那么它将从预提交阶段进入提交状态,并向所有参与者发送doCommit请求事务提交
参与者收到doCommit请求后,正式提交事务,并在完成事务提交后释放占用的资源反馈事务提交结果
参与者完成事务提交后,向协调者发送ACK信息完成事务
协调者接收到所有参与者ack信息,完成事务
(2)中断事务
假设协调者正常工作,并且有任一参与者反馈No,或者在等待超时后无法接收所有参与者的反馈,都会中断事务
发送中断请求
协调者向所有参与者节点发送abort请求事务回滚
参与者接收到 abort 请求后,利用 undo 日志执行事务回滚,并在完成事务回滚后释放占用的资源反馈事务回滚结果
参与者在完成事务回滚之后,向协调者发送 ack 信息中断事务
协调者接收到所有参与者反馈的 ack 信息后,中断事务。
阶段三可能出现的问题:
协调者出现问题、协调者与参与者之间网络出现故障。不论出现哪种情况,最终都会导致参与者无法及时接收到来自协调者的 doCommit 或是 abort 请求,针对这种情况,参与者都会在等待超时后,继续进行事务提交(timeout 后中断事务)。
2.2 优缺点
优点:降低参与者阻塞范围,并能够在出现单点故障后继续达成一致
缺点:引入 preCommit 阶段,在这个阶段如果出现网络分区,协调者无法与参与者正常通信,参与者依然会进行事务提交,造成数据不一致。
三、Paxos(解决单点问题)
Paxos 算法目的是让整个集群的结点对某个值的变更达成一致。Paxos 算法(强一致性算法)属于多数派——大多数的决定会成个整个集群的统一决定。任何一个点都可以提出要修改某个数据的提案,是否通过这个提案取决于这个集群中是否有超过半数的结点同意(所以 Paxos 算法需要集群中的结点是单数)
这个算法有两个大阶段,四个小阶段(Paxos 有 Proposer 和 Acceptor 两个角色)
Prepare
proposer 提出一个提案,编号为 N ,此 N 大于这个 proposer 之前提出提案编号。请求 acceptors 的 quorum 接受。Promise
如果 N 大于此 acceptor 之前接受的任何提案编号则接受,否则拒绝Accept
如果达到了多数派, Proposer 会发出 accept 请求,此请求包含提案编号 N,以及提案内容Accepted
如果此 acceptor 在此期间没有收到任何编号大于 N 的提案,则接受此提案内容,否则忽略
下面详细解释一下这四个阶段(A 为 Proposer, A、B、C 均为 Acceptor)
第一阶段:Prepare 阶段
A 把申请修改的请求 Prepare Request 发给所有的结点 A,B,C。注意,Paxos 算法会有一个 Sequence Number(你可以认为是一个提案号,这个数不断递增,而且是唯一的,也就是说 A 和 B 不可能有相同的提案号),这个提案号会和修改请求一同发出,任何结点在 “Prepare 阶段” 时都会拒绝其值小于当前提案号的请求。所以,结点 A 在向所有结点申请修改请求的时候,需要带一个提案号,越新的提案,这个提案号就越是是最大的。
如果接收结点收到的提案号 n 大于其它结点发过来的提案号,这个结点会回应 Yes(本结点上最新的被批准提案号),并保证不接收其它 <n 的提案。这样一来,结点上在 Prepare 阶段里总是会对最新的提案做承诺。
优化:在上述 prepare 过程中,如果任何一个结点发现存在一个更高编号的提案,则需要通知提案人,提醒其中断这次提案。
第二阶段:Accept 阶段
如果提案者 A 收到了超过半数的结点返回的 Yes,然后他就会向所有的结点发布 Accept Request(同样,需要带上提案号 n),如果没有超过半数的话,那就返回失败。
当结点们收到了 Accept Request 后,如果对于接收的结点来说,n 是最大的了,那么,它就会通过 request(修改这个值),如果发现自己有一个更大的提案号,那么,结点就会拒绝 request(拒绝修改)。
我们可以看以,这似乎就是一个“两段提交”的优化。其实,2PC/3PC 都是分布式一致性算法的残次版本,Google Chubby 的作者 Mike Burrows 说过这个世界上只有一种一致性算法,那就是 Paxos,其它的算法都是残次品。
我们还可以看到:对于同一个值的在不同结点的修改提案就算是在接收方被乱序收到也是没有问题的。
四、Raft(解决 Paxos 的实现难度)
Raft 是简化版的 Paxos。Raft 划分成三个子问题:一是Leader Election;二是 Log Replication;三是 Safety。Raft 定义了三种角色 Leader、Follower、Candidate,最开始大家都是 Follower,当 Follower 监听不到 Leader,就可以自己成为 Candidate,发起投票。
4.1 Leader 选举:timeout 限制
每个 Follower 都在 150ms and 300ms 之间随机超时,之后看谁先 timeout,谁就先成为 Candidate,然后它会先投自己一票,再向其他节点发起投票邀请。如果其他节点在这轮选举还没有投过票,那么就给 Candidate 投票,然后重置自己的选举 timeout。如果得到大多数的投票就成为 Leader,之后定期开始向 Follower 发送心跳。
如果两个 Follower 同时成为 Candidate 的话,如果最后得到的票数相同,则等待其他 Follower 的选择 timeout 之后成为 Candidate,继续开始新一轮的选举。
4.2 log复制
Leader 把变动的 log 借助心跳同步给 Follower,过半回复之后才成功提交,之后再下一次心跳之后,Follower 也 commit 变动,在自己的 node 上生效。
分裂之后,另一个分区的 Follower 接受不到 Leader 的 timeout,然后会有一个先 timeout,成为 Candidate,最后成为 Leader。于是两个分区就有了两个 Leader。
当客户端有变动时,其中的 Leader 由于无法收到过半的提交,则保持未提交状态。有的 Leader 的修改,可以得到过半的提交,则可以修改生效。
当分裂恢复之后,Leader 开始对比选举的 term,发现有更高的 term 存在时,他们会撤销未提交的修改,然后以最新的为准。
五、ZAB
基本与 raft 相同。在一些名词的叫法上有些区别,如 ZAB 将某一个 Leader 的周期称为 epoch,而 raft 则称之为 term。实现上也有些许不同,如 raft 保证日志连续性,心跳方向为 Leader 至 Follower,ZAB 则相反。
参考:
- 《分布式理论系列》:https://segmentfault.com/a/1190000004474543
- 从 Paxos 到 Zookeeper : 分布式一致性原理与实践
- 《一致性算法(Paxos、Raft、ZAB)视频》:https://www.bilibili.com/video/av21667358/
- 《分布式事务中2PC与3PC的区别》:https://blog.csdn.net/yyd19921214/article/details/68953629
每天用心记录一点点。内容也许不重要,但习惯很重要!
分布式理论系列(二)一致性算法:2PC 到 3PC 到 Paxos 到 Raft 到 Zab的更多相关文章
- 分布式一致性算法2PC和3PC
为了解决分布式一致性问题,产生了不少经典的分布式一致性算法,本文将介绍其中的2PC和3PC.2PC即Two-Phase Commit,译为二阶段提交协议.3PC即Three-Phase Commit, ...
- 分布式一致性算法 2PC 3PC Paxos
分布式一致性算法的目的是为了解决分布式系统 一致性算法可以通过共享内存(需要锁)或者消息传递实现,本文讨论后者实现的一致性算法,不仅仅是分布式系统中,凡是多个过程需要达成某种一致的场合都可以使用. 本 ...
- 分布式理论系列(三)ZAB 协议
分布式理论系列(三)ZAB 协议 在学习了 Paxos 后,接下来学习 Paxos 在开源软件 Zookeeper 中的应用. 一.Zookeeper Zookeeper 致力于提供一个高性能.高可用 ...
- 分布式理论系列(一)从 ACID 到 CAP 到 BASE
分布式理论系列(一)从 ACID 到 CAP 到 BASE 一.ACID 1.1 事务的四个特征: (1) Atomic(原子性) 事务必须是一个原子的操作序列单元,事务中包含的各项操作在一次执行过程 ...
- 一致性算法—Paxos、Raft、ZAB
一致性算法—Paxos.Raft.ZAB 2019年04月21日 20:35:09 bulingma 阅读数 64更多 分类专栏: 分布式概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY ...
- [转帖]【ZOOKEEPER系列】Paxos、Raft、ZAB
[ZOOKEEPER系列]Paxos.Raft.ZAB 2018-07-11 12:09:49 wangzy-nice 阅读数 2428更多 分类专栏: zookeeper 版权声明:本文为博主原 ...
- 分布式一致性协议-2PC与3PC(二)
一.分布式一致性 一个事务需要跨多个分布式节点,又要保持事务的ACID特性,需要引入协调者来统一调度所有分布式节点的执行逻辑,被调度的节点称为参与者. 协调者负责调用参与者,并决定最终是否提交事务.基 ...
- 三:分布式事务一致性协议2pc和3pc
一:分布式一致性协议--->对于一个分布式系统进行架构设计的过程中,往往会在系统的可用性和数据一致性之间进行反复的权衡,于是就产生了一系列的一致性协议.--->长期探索涌现出一大批经典的一 ...
- 分布式系统理论基础1: 一致性、2PC和3PC
本文转自 https://www.cnblogs.com/bangerlee/p/5268485.html 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...
随机推荐
- brave-zipkin的日志源码分析
其实在zipkin的日志里面作为发送端日志两个,sr,ss,这个日志是servlet产生的:接收端日志是四个,分别是cr,sr,ss,cs:cr和cs分别是上游的日志的信息:ss和sr是接收端输出的日 ...
- 64位windows 2003和windows xp
msdn windows2003 64位简体中文企业版R2 sp2(cn_win_srv_2003_r2_enterprise_x64_with_sp2_vl) ed2k://|file|cn_win ...
- Top Android App使用的组件(应用)
Top Android App使用的组件 唱吧_462 smack:de.measite.smack:??? ???:org.apache:??? smack:org.jivesoftware.s ...
- C++ 内连接与外连接 (转)
啥叫内连接 外连接 我们知道编译的时候(假如编译器是VS),是以源文件cpp文件为单位,编译成一个个的obj文件,然后再通过链接器把不同的obj文件链接起来. 简单的说,如果一些变量或函数的定义是内连 ...
- Spring cloud 之Feign基本使用
首先导入feign的依赖: <!-- 添加feign声明式webservice client --> <dependence> <groupId>org.sprin ...
- 【ZZ】国外大型网站使用到编程语言 | 菜鸟教程
http://www.runoob.com/w3cnote/rogramming-languages-used-in-most-popular-websites.html 下图展示了大型网站使用到的后 ...
- jsp获取请求头信息
<%@ page language="java" import="java.util.*" contentType="text/html; ch ...
- 熟练使用Linux进程管理类命令
进程管理类命令 – ps命令 ps命令主要用于查看系统的进程 该命令的语法为:ps [参数] ps命令的常用参数选项有: -a:显示当前控制终端的进程(包含其他用户的). -u:显示进程的用户名和启动 ...
- css字体中px和em的区别
2015-05-28 昨天看到一个不错的纯css3表格样式,看到代码后注意到了作者用的都是em在控制大小.顿时想到了自己习惯使用的px长度单位,就查了关于两者的区别.综合前辈们的总结记录整理下来,以供 ...
- android 学习 之 布局(上)
学习安卓布局前,先了解三个属性值: 1.fill_parent: 设置一个构件的布局为fill_parent将强制性地使构件扩展,以填充布局单元内尽可能多的空间 2.match_parent: And ...