2PC 、 3PC 、 Paxos 、 ZAB、Lease
在分布式应用中,每个节点都知道自己的事务提交是成功或者失败,但是无法直接获取其他分布式节点的结果。因此需要一个协调者,其他节点称为参与者。
一、2PC:
提交事务请求,执行事务提交。同步阻塞、单点故障、数据不一致、太过保守(没有较好的容错机制,任何一个节点出现故障,都会导致事务失败,当某个节点出现故障时,协调者只能通过超时机制判断是都终止)。主要用于数据库领域,解决了分布式事务的原子性问题。
1、提交事务请求
首先向其他节点询问是否可以执行事务提交操作,并发送事务给各个节点;
然后各个节点执行事务,并将操作写入本地事务日志
各个参与者向协调者发送反馈。
2、执行事务提交
(1)若协调者受到了所有参与者的ACK反馈;
向所有的参与者发送Commit消息;
参与者收到Commit消息后执行事务提交操作,并向协调者发送ACK反馈,然后释放事务资源;
协调者受到反馈后完成事务。
(2)若协调者收到了某一个参与者的NO反馈,或者协调者等待超时之后;
向所有参与者节点发送回滚请求;
参与者收到后执行回滚请求;
执行完后向协调者发送ACK反馈;
协调者接收到所有参与者的ACK反馈后完整事务中断。
二、3PC:
cancommit,precommit,docommit;单点故障、数据不一致,解决了同步阻塞问题(超时提交策略,第三阶段参与者等待超时后会提交事务)。由于precommmit解决了同步折射问题。
1、cancommit
协调者向所有参与者发送包含事务内容在内的cancommit请求,并等待参与者的反馈;
参与者收到cancommit请求后,若判断自己可以顺利执行事务,则向协调者发送ACK响应,否则反馈NO响应。
2、precommit
若协调者收到了所有参与者的ACK响应,则向所有的参与者发送precommit请求;
参与者收到后执行事务,并将操作写入本地事务日志,成功后向协调者发送ACK响应;
若协调者在第一阶段的反馈中有NO,或者协调者等待超时,则向所有的参与者发送中断请求。
3、docommit
(1)如果协调者收到了第二阶段的所有参与者的ACK请求,则向参与者发送docommit请求执行事务的提交;
参与者收到docommit请求后执行事务的提交,成功后释放事务资源;
参与者事务提交后向协调者发送ACK反馈;
协调者收到所有参与者反馈后,完成事务的提交。
(2)若协调者等待超时,或者第二阶段中有参与者发送NO反馈,则会向所有参与者发送中断请求;
参与者收到后执行事务回滚,回滚结束后释放事务资源,向协调者发送ACK响应;
协调者收到所有的ACK响应后中断事务。
3PC与2PC相比,引入了超时机制,可以降低事务资源的阻塞范围
在第一第二阶段,若协调者等待超时,会执行中断操作,第三阶段若参与者等待超时,会继续执行commit操作
优点:降低了阻塞范围,不会产生同步阻塞。即每一个参与者在等待超时之后会提交事务请求,不必等待其他参与者的
反馈。
引入超时之后,第三阶段使得即使出现单点故障之后,参与者在时间内未收到协调者信息,最终仍会提交事务,达成一
致性。
缺点:由于引入超时,在precommit之后,若协调者与参与者之间出现通信故障,导致参与者未收到来自协调者的中断
信息,参与者会执行提交操作,导致数据不一致。
三、Paxos算法:
Paxos算法是一种基于消息传递的且具有高度容错性的一种算法,解决的问题是一个分布式系统如何就某个值(决议)达成一致。该算法前提是假设不存在拜占庭将军问题。在该算法中一共有三种角色:proposer、acceptor、learner。proposer负责提出提案,acceptor负责对天做出裁决,learner负责学得到的提案。为了避免单点的故障,会有一个acceptor集合,proposer向该集合发送提案,当有一半以上的成员同意,则同意该提案。
主要过程有两部分,prepare阶段和accept阶段。
prepare阶段:proposer提出编号为Mn的提案,向acceptor集合发送prepare请求。acceptor做出反馈:保证不会再接受编号比Mn小的提案;如果acceptor已经批准过某提案,会向proposer返回已经批准的编号最大的提案的value值。
如果acceptor收到一个编号为Mn的请求且编号大于acceptor已经响应的所有prepare请求的编号,则它会将自己已经批准过的编号最大的提案值反馈给proposer,同时acceptor承诺不会再接受编号比Mn小的提案。(优化:忽略编号小于已批准的提案的请求)
如果proposer收到了集合至少一半的响应,则会发送一个针对Mn、Vn的accept请求给acceptor。Vn为收到的所有响应中编号最大的提案的值。如果响应不包含值,则可以由proposer选择任意值。
accept阶段:acceptor收到accept请求后,只要未收到任何编号大于Mn的prepare请求,则通过该提案。
优化:为了避免死循环,比如两个proposer一次提出一系列编号递增的提案。可以产生一个主proposer,提案只能由主proposer负责提出。
learner学习三种策略:
(1)acceptor接受了一个提案,就将该提案发送给所有learner。
优点:learner能快速获取被选定的value
缺点:通信的次数为(M*N)
(2)acceptor接受了一个提案,就将该提案发送给主learner,主learner再通知其他learner。
优点:通信次数减少(M+N-1)
缺点:单点问题,主learner可能出现故障
(3)acceptor接受了一个提案,就将该提案发送给一个learner集合,learner集合再通知其他learner。
优点:集合中的learner个数越多,可靠性越好
缺点:网络通信负责度越高
四、ZAB协议:
ZAB协议:是为Zookeeper专门设计的一种支持崩溃恢复的消息广播协议。ZAB协议只允许有一个主进程接受客户事务请求并处理,即leader。当leader收到请求后,将请求事务转化为事务proposal,由于leader会为每一个follower创建一个队列,将该事务放入响应队列,保证事务的顺序性,之后会在队列中顺序向其他节点广播该提案,follower收到会将其以事务的形式写入到本地日志中,并向leader发送反馈ack。leader会等待其他follower的回复,当收到一半以上的follower响应时,leader会向其他节点发送commit消息,同时leader提交该提案。
ZAB有两种模式:故障恢复模式以及消息广播。
当系统启动或者leader服务器出现故障等现象时,进入故障恢复模式。将会开启新的一轮选举。选举产生的leader会与过半的follower进行同步,使数据一致,当同步结束后,退出恢复模式,进入消息广播模式。当一台遵从ZAB协议的服务器启动后,如果检测到有leader在广播消息,会自动进入恢复模式,当其完成与leader的同步以后,进入消息广播模式。如果集群中的非leader节点收到客户端请求,非leader节点会先将请求发送到leader服务器。
故障恢复如下:
ZAB协议需要保证已经被leader提交的事务最终被所有的机器提交;
ZAB协议需要保证丢弃那些只在leader上提出的事务;
为了保证以上两点,选举时如果选择ZXID最大的节点就可以解决上述的问题。数据同步是为每一个follower创建一个队列,leader将各个follower没有提交的事务写入各个队列,并发送给各个follower。follower将事务同步后leader将其加入真正可用的follower列表。
leader重新选举的条件:leader宕机或发生故障,集群中少于一般的节点与当前leader保持连接。
五、Lease:
Lease是一种带期限的契约,在此期限内拥有 lease 的节点有权利操作一些预设好的对象,一般把拥有 Lease 节点称为 Master 。从更深层次上来看,Lease就是一把带有超时机制的分布式锁,如果没有 Lease ,分布式环境中的锁可能会因为锁拥有者的失败而导致死锁,有了 Lease 死锁会控制在超时时间之内。典型的应用在 HDFS 中 namenode 与 client 之间的租约恢复。