目录
一致性协议
2PC二阶段提交
二阶段提交存在的问题:
3PC 三阶段提交
优点
Paxos算法
流程演变
Paxos优缺点
活锁问题
ZAB协议(Fast Paxos)
一致性协议
事务需要跨多个分布式节点时,为了保证事务的ACID特性,需要选举出一个协调者来协调分布式各个节 点的调度,基于这个思想衍生了多种一致性协议:
2PC二阶段提交
阶段一 提交事务请求
- 协调者向所有的参与者节点发送事务内容,询问是否可以执行事务操作,并等待其他参与者节点的反馈
- 各参与者节点执行事务操作
- 各参与者节点反馈给协调者,事务是否可以执行
阶段二 事务提交
根据一阶段各个参与者节点反馈的ack,如果所有参与者节点反馈ack,则执行事务提交,否则中断事务
事务提交:
- 协调者向各个参与者节点发送commit请求
- 参与者节点接受到commit请求后,执行事务的提交操作
- 各参与者节点完成事务提交后,向协调者返送提交commit成功确认消息
- 协调者接受各个参与者节点的ack后,完成事务commit
中断事务:
- 发送回滚请求
- 各个参与者节点回滚事务
- 反馈给协调者事务回滚结果
- 协调者接受各参与者节点ack后回滚事务
二阶段提交存在的问题:
-
同步阻塞
二阶段提交过程中,所有参与事务操作的节点处于同步阻塞状态,无法进行其他的操作
-
单点问题
一旦协调者出现单点故障,无法保证事务的一致性操作
-
脑裂导致数据不一致
如果分布式节点出现网络分区,某些参与者未收到commit提交命令。则出现部分参与者完成数据提交。未收到commit的命令的参与者则无法进行事务提交,整个分布式系统便出现了数据不一致性现象。
3PC 三阶段提交
3PC是2PC的改进版,实质是将2PC中提交事务请求拆分为两步,形成了CanCommit、PreCommit、 doCommit三个阶段的事务一致性协议
阶段一 : CanCommit
1、事务询问
2、各参与者节点向协调者反馈事务询问的响应
阶段二 : PreCommit
根据阶段一的反馈结果分为两种情况
1、执行事务预提交
- 1)发送预提交请求 协调者向所有参与者节点发送preCommit请求,进入prepared阶段
- 2)事务预提交 各参与者节点接受到preCommit请求后,执行事务操作
- 3)各参与者节点向协调者反馈事务执行
2、中断事务
任意一个参与者节点反馈给协调者响应No时,或者在等待超时后,协调者还未收到参与者的反馈,就中断事务,中断事务分为两步:
- 1)协调者向各个参与者节点发送abort请求
- 2)参与者收到abort请求,或者等待超时时间后,中断事务
阶段三 : doCommit
1、执行提交
- 1)发送提交请求 协调者向所有参与者节点发送doCommit请求
- 2)事务提交 各参与者节点接受到doCommit请求后,执行事务提交操作
- 3)反馈事务提交结果 各参与者节点完成事务提交以后,向协调者发送ack
- 4)事务完成 协调者接受各个参与者反馈的ack后,完成事务
2、中断事务
- 1)参与者接受到abort请求后,执行事务回滚
- 2)参与者完成事务回滚以后,向协调者发送ack
- 3)协调者接受回滚ack后,回滚事务
3PC相较于2PC而言,解决了协调者挂点后参与者无限阻塞和单点问题,但是仍然无法解决网络分区问题
优点
- 首先对于协调者和参与者都设置了超时机制(在2PC中,只有协调者拥有超时机制,即如果在一定时间内没有收 到参与者的消息则默认失败),主要是避免了参与者在长时间无法与协调者节点通讯(协调者挂掉了)的情况下,无法释放资源的问题,因为参与者自身拥有超时机制会在超时后,自动进行本地commit从而进行释放资源。而这种机制也侧面降低了整个事务的阻塞时间和范围。
- 通过CanCommit、PreCommit、DoCommit三个阶段的设计,相较于2PC而言,多设置了一个缓冲阶段保证了在最后提交阶段之前各参与节点的状态是一致的
Paxos算法
Paxos算法是Leslie Lamport 1990年提出的一种一致性算法,该算法是一种提高分布式系统容错性的一致性算法,解决了3PC中网络分区的问题,paxos算法可以在节点失效、网络分区、网络延迟等各种异常情况下保证所有节点都处于同一状态,同时paxos算法引入了“过半”理念,即少数服从多数原则。(主要是为了选Leader)
paxos有三个版本:
-
Basic Paxos
-
Multi Paxos
-
Fast Paxos
在paxos算法中,有四种种角色,分别具有三种不同的行为,但多数情况,一个进程可能同时充当多种角色。
-
client:系统外部角色,请求发起者,不参与决策
-
proposer:提案提议者
-
acceptor:提案的表决者,即是否accept该提案,只有超过半数以上的acceptor接受了提案,该 提案才被认为被“选定”
-
learners:提案的学习者,当提案被选定后,其同步执行提案,不参与决策
Paxos算法分为两个阶段:prepare阶段、accept阶段
-
prepare阶段
- proposer提出一个提案,编号为N,发送给所有的acceptor。
- 每个表决者都保存自己的accept的最大提案编号maxN,当表决者收到prepare(N)请求时,会 比较N与maxN的值,若N小于maxN,则提案已过时,拒绝prepare(N)请求。若N大于等于maxN, 则接受提案,并将该表决者曾经接受过的编号最大的提案Proposal(myid,maxN,value)反馈给提议者:其中myid表示表决者acceptor的标识id,maxN表示接受过的最大提案编号maxN,value表 示提案内容。若当前表决者未曾accept任何提议,会将proposal(myid,null,null)反馈给提议者。
-
accept阶段
- 提议者proposal发出prepare(N),若收到超过半数表决者acceptor的反馈,proposal将真正的 提案内容proposal(N,value)发送给所有表决者。
- 表决者acceptor接受提议者发送的proposal(N,value)提案后,会将自己曾经accept过的最大 提案编号maxN和反馈过的prepare的最大编号,若N大于这两个编号,则当前表决者accept该提案,并反馈给提议者。否则拒绝该提议。
- 若提议者没有收到半数以上的表决者accept反馈,则重新进入prepare阶段,递增提案编号, 重新提出prepare请求。若收到半数以上的accept,则其他未向提议者反馈的表决者称为learner,主动同步提议者的提案。
流程演变
-
正常流程
-
单点故障,部分节点失败
-
proposer失败
-
Basic Paxos算法存在活锁问题(liveness)或dueling,而且较难实现
-
Multi Paxos: 唯一的proposor,即leader
-
简化角色
Paxos优缺点
优点:paxos算法的优点很明显,按照此方法可以对多个数据值达到一致,收敛较好。
缺点:paxos算法的缺点是会出现活锁问题,考虑到一种极端的情况下,有两个proposer依次提出了一系列编号递增的议案,但是最终paxos无法形成最终的议案。
活锁问题
活锁就是永远不会结束的锁
-
Acceptor不再应答Proposal 提案号小于等于当前请求的Prepare请求
-
意味着需要应答Proposal 提案号大于当前请求的Prepare请求
-
两个Proposers交替Prepare成功,而Accept失败,形成活锁(Livelck)
-
两个值会一直保持失败的状态
解决方式:稍微错开时间即可
ZAB协议(Fast Paxos)
由于paxos算法实现起来较难,存在活锁和全序问题(无法保证两次最终提交的顺序),所以 zookeeper并没有使用paxos作为一致性协议,而是使用了ZAB协议。
ZAB(zookeeper atomic broadcast):是一种支持崩溃恢复的原子广播协议,基于Fast Paxos实现