Paxos&Raft算法介绍

Paoxs算法介绍

Paxos算法是莱斯利·兰伯特于1989年提出的一种基于消息传递模型的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。

在一个分布式系统中,数据往往以多副本的形式存储在不同节点上,如分布式数据库系统,用户对系统的更新请求会同时发送给各个节点。但实际上系统是不可靠的,如节点可能会宕机、消息处理可能会慢、程序可能出故障,网络可能会延迟、中断等。如何在上述系统中保证在任何异常情况下,都不会破坏各个节点的数据一致性,正是Paxos要解决的问题。

1.   背景

传统的主从同步无法同时保证数据的一致性和可用性,分布式系统中著名的CAP理论从理论上证明了这个问题。CAP理论告诉我们C、A、P三者不能同时满足,最多只能满足其中两个。

一般来说使用网络通信的分布式系统,无法舍弃P性质,那么就只能在一致性和可用性上做一个艰难的选择。既然在分布式系统中一致性和可用性只能选一个。那Paxos、Raft等分布式一致性算法是如何做到在保证一定的可用性的同时,对外提供强一致性呢。

 

  1. 首先,由于分区很少发生,那么在系统不存在分区的情况下没什么理由牺牲C或A;
  2. 其次,C与A之间的取舍可以在同一系统内以非常细小的粒度反复发生,而每一次的决策可能因为具体的操作,乃至因为牵涉到特定的数据或用户而有所不同;
  3. 最后,这三种性质都可以在程度上衡量,并不是非黑即白的有或无。可用性可以在0%到100%之间连续变化的,一致性分很多级别,连分区也可以细分为不同含义,如系统内的不同部分对于是否存在分区可以有不一样的认知。

 

所以一致性和可用性并不是水火不容,非此即彼的。Paxos、Raft等分布式一致性算法就在一致性和可用性之间做到了很好的平衡。

2.   算法原理

Paxos算法运行在允许宕机故障的异步系统中,不要求可靠的消息传递,可容忍消息丢失、延迟、乱序以及重复。它利用大多数 (Majority) 机制保证了2F+1的容错能力,即2F+1个节点的系统最多允许F个节点同时出现故障。

Paxos将系统中的角色分为提议者 (Proposer),决策者 (Acceptor),和最终决策学习者 (Learner):

Proposer: 提出提案 (Proposal)。Proposal信息包括提案编号 (Proposal ID) 和提议的值 (Value)。

Acceptor:参与决策,回应Proposers的提案。收到Proposal后可以接受提案,若Proposal获得多数Acceptors的接受,则称该Proposal被批准。

Learner:不参与决策,从Proposers/Acceptors学习最新达成一致的提案(Value)。

 

一个或多个提议进程 (Proposer) 可以发起提案 (Proposal),Paxos算法使所有提案中的某一个提案,在所有进程中达成一致。系统中的多数派同时认可该提案,即达成了一致。最多只针对一个确定的提案达成一致。在多副本状态机中,每个副本可以在Proposer、Acceptor、Learner三种角色中转换。

 

Paxos算法通过一个决议分为两个阶段(Learn阶段之前决议已经形成):

  1. 第一阶段:Prepare阶段。Proposer向Acceptors发出Prepare请求,Acceptors针对收到的Prepare请求进行Promise承诺。
  2. 第二阶段:Accept阶段。Proposer收到超过半数Acceptors承诺的Promise后,向Acceptors发出Propose请求。Acceptors针对收到的Propose请求进行Accept处理。
  3. 第三阶段:Learn阶段。Proposer在收到多数Acceptors的Accept之后,标志着本次Accept成功,决议形成,将形成的决议发送给所有Learners。

Paxos算法伪代码描述如下:

 

  1. 获取一个Proposal ID n,为了保证Proposal ID唯一,可采用时间戳+Server ID生成;
  2. Proposer向所有Acceptors广播Prepare(n)请求;
  3. Acceptor比较n和minProposal,如果n>minProposal,minProposal=n,并且将 acceptedProposal 和 acceptedValue 返回;
  4. Proposer接收到过半数回复后,如果发现有acceptedValue返回,将所有回复中acceptedProposal最大的acceptedValue作为本次提案的value,否则可以任意决定本次提案的value;
  5. 到这里可以进入第二阶段,广播Accept (n,value) 到所有节点;
  6. Acceptor比较n和minProposal,如果n>=minProposal,则acceptedProposal=minProposal=n,acceptedValue=value,本地持久化后,返回;否则,返回minProposal。
  7. 提议者接收到过半数请求后,如果发现有返回值result >n,表示有更新的提议,跳转到1;否则value达成一致。

第一阶段是为了获取集群中存储的最新的那条数据,第二阶段是为了将这条最新的数据同步到所有节点。在集群数据达成一致后,Proposer再次广播与上次相同的Prepare(n)请求时,由于n已经和Acceptor中保存的minProposal相等,Acceptor将不会返回acceptedProposal 和 acceptedValue,此时若用户希望执行更新操作,Proposer即可将用户需要更新的值设为本次提案的value,从而在第二阶段将value同步给所有节点。

当集群中存在多个Proposer,且提出了不同提案value时,因为消息到达顺序的不可控,有可能a节点先收到了Proposer1的提案value1,b节点先收到了Proposer2的提案value2,假设Proposer1的Proposer ID大于Proposer2的Proposer ID,则当a节点收到Proposer2的提案时,由于minProposal>n,将直接返回minProposal。此时Proposer2收到a节点的返回发现result >n,将重新进入阶段一,进行集群同步。

 

 

引用

[1] https://zhuanlan.zhihu.com/p/31727291

[2] https://zhuanlan.zhihu.com/p/31780743

 

 

Raft算法介绍

参见

https://zhuanlan.zhihu.com/p/32052223

https://www.infoq.cn/article/raft-paper

 

 

Paxos&Raft算法比较

 

raft是paxos算法的一种改进,一种简化,一种优化,一种具象化。Raft容易实现在于它的描述是非常规范的,包括了所有的实现细节。如上面的人说的有如伪代码。

paxos的描述侧重于理论,工程实现按照谷歌chubby论文中的说话,大家从paxos出现,写着写着,处理了n多实际中的细节之后,已经变成另外一个算法了,这时候正确性已经无法得到理论的保证。

 

但是 Raft 协议做了一个约束,数据库的多个投票多条日志一定要按照顺序执行,只有前一个日志被确认了才能再确认后一个日志。导致了两个问题,第一个问题是并发能力变差了。以前支持并发的提交,现在只能支持一个结束以后再进入下一个,所以它的性能变差了。第二个是可用性的问题。如果采用 Paxos 协议,当一台机器新上线的时候很快就能提供服务,因为不需要等前面的数据确认就能提供服务,但是如果使用的是 Raft 协议,需要等前面的所有日志确认以后才能提供服务,所以说 Raft 协议存在可用性的风险。

 

引用

[1] https://www.zhihu.com/question/36648084

[2] https://www.oceanbase.com/blog/fzbqhi

[3] https://www.oceanbase.com/blog/mqlia7

posted @ 2022-03-20 23:53  jason_t  阅读(1401)  评论(0编辑  收藏  举报