菜菜

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Paxos

Paxos总共有三个角色
1:提议者(Proposers)
2:接受者(Acceptors)
3:学习者(Learns)
一致性的目标是一组参与者在每次商议中对一个值形成共同的共识。
从Propsers提交值给一组Acceptors开始就开启一次一致性商议,Acceptors在接受某次提案的值,并且超过某次阀值后,这个值就会在网络中传播。
为了让Paxos协议能正常工作,第一个约束是:
Acceptors必须接受它收到的第一个提案的值。

这会导致一个问题,考虑一下这个情况,多个Proposers发送提案的值,多个Acceptors接收到多个值。因为Acceptors只接收第一个收到的值,所以形成不了
大多数结果。Paxos给每次的提案附加唯一的标记来允许Acceptors同时接收到多个提案。

对每次提案附加一个唯一标记,某次提案过程中,如果大多数Acceptors接受提案的值,这个值就叫做chosen value。可以通过多个提案,但是必须保证
多个提案对于同一个值有相同的值。这样就引出第二个约束:
如果已经选择了提案的值 V,每次更高的提案都必须选择值 V。
网络通讯异步进行,所以会存在某些Acceptors未收到chosen value,但是这个并不会违反约束1和约束2.

Propsers在发送消息给acceptors时使用如下几个约束。这个过程叫做prepare request,包含俩个要求。

1.承诺不接受提案标号小于n的提案(n是新的提案标号)。
2.响应acceptor已接受,标号小于n且标号值最大的提案。

根据Lamport的论文
如果Proposers收到大多数的acceptors的响应,那么它就可以提出编号是n,值是v的提案,值v是响应中编号最高的提案的值,如果响应者报告没有提案,宣布的值可以是任何被proposer选择的值。

Proposers然后发送一个accept请求,然后由Acceptor确认。Proposer然后发送一个提交消息给Acceptors,Acceptors可以忽略(不影响安全性)或者表示值已经提交成功。
一旦Acceptors提交的值超过了某个阀值,那么共识过程就结束了,这个值可以在外部使用。

Paxos的复杂性在于它只要大多数节点同意这个值时就可以接受这个值,其他节点可以忽略或者抵制提议的值。以前的协议需要所有的节点达成一致,一旦某个节点失败,协议过程就会被阻塞。

因为每次提案的标号都唯一,所以Paxos能安全选择一个值。必须要注意一点,Acceptor仅需要记录它已经接受的最高提案标号。
相对而说,Proposer能放弃提案,只要它不会发起有相同标号的提案。


Proposer和Acceptor的职责划分如下:
Proposer
1.在prepare request的阶段中,发起编号为n的提案给acceptor,等待大多数acceptor的响应。
2.如果大多数Acceptor同意这个提案,他们会回复同意的值。如果大多数拒绝这个提案,放弃或者重新开始这个过程。
3.如果大多数Acceptor同意提案,Proposer然后发送一个确认消息(包含提案标号n和值)。
4.如果大多数Acceptor收到确认消息,这轮商议就结束了。

Acceptor
1.接收编号为n的提案X,比较X的编号和已经同意的最高提案编号。
2.如果提案X的编号n比较高,接受它,如果n比较低,拒绝它。
3.如果值和先前接受的提案值一样或者它的提案编号高于同意的提案,接受后期的确认消息。

Proposals可以同时发起多个提案,但是需要遵循单个提案的算法。


最后,Learners发现大多数Acceptors已经接受的提案。当然,一个Learner也可以把发现的提案值广播给其他的Learners。
同样也可以这个实现这个过程,Acceptor同志对应的Learners或者Acceptros告诉一组不同的Learners,然后由Learners通知其他的Learners。

形式上来说,Paxos在每次过程中都会区分出来leader(Proposer),Acceptors能确认那个proposer是它的leader,这样就可以在集群选举leader
的过程中使用Paxos。使用Paxos进行选举可能会出现俩个Proposer竞争leader位置的情形,但是,这个情况应该不会持续太久。

 


Raft

Raft在保证容错和性能的前提下构建了一个更容易理解的Paxos版本。由于Paxos太过于复杂,所以不适合使用在基础平台。Raft和Paxos类似,所以进行比较之前
需要简单说明一下Raft为什么比Paxos简单。

Raft使用leader和follower模型,并且假设集群只有一个leader。leader管理着参与节点的日志复制功能,一旦leader断开,参与者就会立即替代leader。

在算法开始前,leader就已经被选好,为了给leader选举过程一些上下文信息,leader在一致性中扮演着特定的角色,并且在每个特定的算法中都不同。比如,在Nakamoto Proof of work中,
在每轮leader选举过程中使用lottery,每轮选举大概10分钟。Practical Byzantine Fault Tolerance(PBFT)中,leader选举使用随机方式。

在Raft中,由candidate节点开始一个初始过程来选举leader。如果出现选举超时(election timeout),此时candidates未收到任何信息,candidates就会增加自己的
term-counter,然后把票投给自己,然后广播这个结果给其他节点。如果其他的candidates的值比当前的candidates的大,当前的candidate就变成了follower。
这个规则持续影响到其他candidate,直到某个candidate得到大多数的投票。

leader控制节点之间的日志复制,并且发送客户端请求到它的follower上。如果大多数followers确认了复制,那么请求就可以提交。Followers同样把提交的数据给本地的机器。

Raft的容错性实现,新的leader强制自己followers复制自己的日志。任何没有同意的项都应该被删除,这样就可以保证日志一致性。

leader的日志需要比follower的日志新,如果某个candidate的日志比部分follower的旧,那么这个candidate就会被拒绝。

总的来说,Raft把一致性分成三个单独的子问题:
1.leader选举
2.日志复制
3.安全

 

posted on 2019-10-08 17:46  好吧,就是菜菜  阅读(2352)  评论(0编辑  收藏  举报