分布式一致性算法(二)Paxos算法

来源:互联网 发布:物联网域名注册 编辑:程序博客网 时间:2024/05/17 02:18

转载:对分布式事务及两阶段提交、三阶段提交的理解

转载:paxos算法之粗浅理解

转载:Paxos算法与Zookeeper分析

转载:三:ZooKeeper的ZAB协议

何为一致性问题?简单而言,一致性问题就是相互独立的节点之间如何达成一项决议的问题。分布式系统中,进行数据库事务提交(commit transaction)、Leader选举、序列号生成等都会遇到一致性问题。

一 2PC和3PC

两阶段提交协议(two phase commit protocol,2PC)可以保证数据的强一致性,许多分布式关系型数据管理系统采用此协议来完成分布式事务。该算法能够解决很多的临时性系统故障(包括进程、网络节点、通信等故障),被广泛地使用。但是,它并不能够通过配置来解决所有的故障,在某些情况下它还需要人为的参与才能解决问题。参与者为了能够从故障中恢复,它们都使用日志来记录协议的状态,虽然使用日志降低了性能但是节点能够从故障中恢复。
在两阶段提交协议中,系统一般包含两类机器(或节点):一类为协调者(coordinator),通常一个系统中只有一个;另一类为事务参与者(participants,cohorts或workers),一般包含多个,在数据存储系统中可以理解为数据副本的个数。顾名思义,两阶段提交协议由两个阶段组成。
在正常的执行下,这两个阶段的执行过程如下所述:
阶段1:请求阶段(commit-requestphase,或称表决阶段,votingphase)
在请求阶段,协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。
阶段2:提交阶段(commitphase)
在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行响应的操作。

 
两阶段提交协议最大的劣势是其通过阻塞完成的协议,在节点等待消息的时候处于阻塞状态,节点中其他进程则需要等待阻塞进程释放资源才能使用。如果协调器发生了故障,那么参与者将无法完成事务则一直等待下去

以下情况可能会导致节点发生永久阻塞:
  1. 如果参与者发送同意提交消息给协调者,进程将阻塞直至收到协调器的提交或回滚的消息。如果协调器发生永久故障,参与者将一直等待,这里可以采用备份的协调器,所有参与者将回复发给备份协调器,由它承担协调器的功能。
  2. 如果协调器发送“请求提交”消息给参与者,它将被阻塞直到所有参与者回复了,如果某个参与者发生永久故障,那么协调器也不会一直阻塞,因为协调器在某一时间内还未收到某参与者的消息,那么它将通知其他参与者回滚事务。
同时两阶段提交协议没有容错机制,一个节点发生故障整个事务都要回滚,代价比较大。

三阶段提交协议在协调者和参与者中都引入超时机制,并且把两阶段提交协议的第一个阶段拆分成了两步:询问,然后再锁资源,最后真正提交。


(1)三个阶段的执行

1.CanCommit阶段

3PC的CanCommit阶段其实和2PC的准备阶段很像。

协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。

2.PreCommit阶段

Coordinator根据Cohort的反应情况来决定是否可以继续事务的PreCommit操作。

根据响应情况,有以下两种可能。

A.假如Coordinator从所有的Cohort获得的反馈都是Yes响应,那么就会进行事务的预执行:

发送预提交请求。Coordinator向Cohort发送PreCommit请求,并进入Prepared阶段。

事务预提交。Cohort接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。

响应反馈。如果Cohort成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。

B.假如有任何一个Cohort向Coordinator发送了No响应,或者等待超时之后,Coordinator都没有接到Cohort的响应,那么就中断事务:

发送中断请求。Coordinator向所有Cohort发送abort请求。

中断事务。Cohort收到来自Coordinator的abort请求之后(或超时之后,仍未收到Cohort的请求),执行事务的中断。

3.DoCommit阶段

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

执行提交

A.发送提交请求。Coordinator接收到Cohort发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有Cohort发送doCommit请求。

B.事务提交。Cohort接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。

C.响应反馈。事务提交完之后,向Coordinator发送ACK响应。

D.完成事务。Coordinator接收到所有Cohort的ACK响应之后,完成事务。

中断事务

Coordinator没有接收到Cohort发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。

三阶段提交协议和两阶段提交协议的不同

对于协调者(Coordinator)和参与者(Cohort)都设置了超时机制(在2PC中,只有协调者拥有超时机制,即如果在一定时间内没有收到cohort的消息则默认失败)。

在2PC的准备阶段和提交阶段之间,插入预提交阶段,使3PC拥有CanCommit、PreCommit、DoCommit三个阶段。

PreCommit是一个缓冲,保证了在最后提交阶段之前各参与节点的状态是一致的。

三阶段提交协议的缺点

如果进入PreCommit后,Coordinator发出的是abort请求,假设只有一个Cohort收到并进行了abort操作,而其他对于系统状态未知的Cohort会根据3PC选择继续Commit,此时系统状态发生不一致性。

二 Paxos算法

Paxos算法是基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。

从提案到表决流程涉及到三个角色:

  • Proposer:提案者,可能有多个,它门负责提出提案。
  • Acceptor:接受人,一定要有多个,它们对指定提案进行表决,同意则接受提案,不同意则拒绝。
  • Learner:学习人,收集每位Acceptor接受的提案,并根据少数服从多数的原则,形成最终提案。

实际上,分布式系统中一个组件可以对应一种或多种角色。

paxos算法主要分为两个阶段:

1. Prepare:

Proposer 向所有Acceptor发送Prepare申请访问权,并携带一个提案号(epoch),Acceptor赋予访问权或拒绝,并且返回该Acceptor 已经接受的值和对应的提案号。如果Proposer获得超过半数Acceptor的访问权,那么会进入第二阶段;

2. Accept:

1) 如果所有的Acceptor返回值都为空,则Proposer将携带自己预设的值v和自己的epoch号向获取到访问权的Acceptor发送请求;

2) 如果Proposer第一阶段获得某些Acceptor的返回值不为空,则将epoch号最大的提案号对应的值f作为自己的预设值,和自己的提案号一起向Acceptor发送请求(如果第一阶段返回f的Acceptor已经超过了半数,则表示已经形成确定性取值,此时直接返回成功,不需要进行Accept请求了);

对于Acceptor来说,当它接收到Proposer请求时,需要应用一系列规则来决定如何响应,我们对这些规则可以进行如下概括:

1)喜新厌旧

当Acceptor接收到Prepare请求时,它将当前自己发放了访问权的epoch号和该Prepare请求携带的epoch进行比较,如果前者小于后者,则将访问权赋予新请求的这个Proposer,否则拒绝发放访问权。这里我们认为epoch值越大的越新

2) 一视同仁

当Acceptor接收到Accept请求时,它将当前自己发放了访问权的epoch号和该Prepare请求携带的epoch进行比较,如果前者大于后者,则拒绝该请求。如果这两个epoch号相等, 并且Acceptor当前接受的取值为空,则接受该Acceptor请求,同时将该Accept请求的值设置为接受值。如果之后又更大的epoch号申请 到访问权,并发出Accept请求,该值也不会改变,即Acceptor在确定了值之后不再改变,谁先设置就用谁的值。虽然在发放访问权时是喜新厌旧,但 在取值这个问题上一视同仁,不会因为新epoch号大而改变取值。

算法优化(fast paxos)

Paxos算法在出现竞争的情况下,其收敛速度很慢,甚至可能出现活锁的情况,例如当有三个及三个以上的proposer在发送prepare请求后,很难有一个proposer收到半数以上的回复而不断地执行第一阶段的协议

因此,为了避免竞争,加快收敛的速度,在算法中引入了一个Leader这个角色,在正常情况下同时应该最多只能有一个参与者扮演Leader角色,而其它的参与者则扮演Acceptor的角色,同时所有的人又都扮演Learner的角色。

在这种优化算法中,只有Leader可以提出议案,从而避免了竞争使得算法能够快速地收敛而趋于一致,此时的paxos算法在本质上就退变为两阶段提交协议。但在异常情况下,系统可能会出现多Leader的情况,但这并不会破坏算法对一致性的保证,此时多个Leader都可以提出自己的提案,优化的算法就退化成了原始的paxos算法

一个Leader的工作流程主要有分为三个阶段:

(1).学习阶段 向其它的参与者学习自己不知道的数据(决议);

(2).同步阶段 让绝大多数参与者保持数据(决议)的一致性;

(3).服务阶段 为客户端服务,提议案;


三 Zookeeper的Paxos

Zookeeper使用了优化版本的Paxos协议,ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeeper Atomic Broadcast(ZAB,zookeeper原子消息广播协议)的协议作为其数据一致性的核心算法。

Zookeeper集群中,主要分为三者角色,而每一个节点同时只能扮演一种角色,这三种角色分别是:

(1). Leader 接受所有Follower的提案请求并统一协调发起提案的投票,负责与所有的Follower进行内部的数据交换(同步);

(2). Follower 直接为客户端服务并参与提案的投票,同时与Leader进行数据交换(同步);

(3). Observer 直接为客户端服务但并不参与提案的投票,同时也与Leader进行数据交换(同步);


ZAB协议的两种基本模式:崩溃恢复模式和消息广播模式。

崩溃恢复模式

      ●ZAB协议会让ZK集群进入崩溃恢复模式的情况如下:

      (1)当服务框架在启动过程

      (2)当Leader服务器出现网络中断,崩溃退出与重启等异常情况。

      (3)当集群中已经不存在过半的服务器与Leader服务器保持正常通信

      ●ZAB协议进入恢复崩溃模式会做什么事情?

      (1)当Leader出现问题,则进入恢复模式并选举出新的Leader服务器。当选举出新的Leader服务器,同时集群中已经有过半的机器与该Leader服务器完成状态同步(数据同步),退出崩溃恢复模式。进入消息广播模式。

      (2)当新加入一台机器到集群中,如果此时集群已经存在一个Leader服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式。找到Leader服务器,并与其进行数据同步,然后进入消息广播模式,一起参与到消息广播流程中去。

ZAB协议和Paxos协议的区别

ZAB协议和Paxos算法的本质区别,两者的设计目标不太一样。ZAB协议主要用于构建一个高可用的分布式数据主备系统。例如ZooKeeper,Paxos算法则是用于构建一个分布式的一致性状态机系统



原创粉丝点击