分布式一致性算法Paxos和Raft

分布式系统的一致性

分布式数据一致性,指的是数据在多份副本中存储时,各个副本中的数据是一致的。

什么是Paxos算法

Paxos由Lamport于1998年在《The Part-Time Parliament》论文中首次公开,它是一种基于消息传递的分布式一致性算法。有相当多的分布式系统都采用了Paxos算法,例如Google的Chubby,Megastore以及Spanner,分布式协调中间件Zookeeper,MySQL中的MySQL Group Replication等等都用到了Paxos算法。

Paxos算法基本概念

Client:客户端
客户端向分布式系统发出请求,并等待响应。例如,对分布式文件服务器中文件的写请求。
Proposer:提案发起者
提案者提倡客户请求,试图说服Acceptor对此达成一致,并在发生冲突时充当协调者以推动协议向前发展
Acceptor:决策者
Acceptor可以批准提案;如果某个提案被选定(chosen),那么该提案里的value就被选定了
Learners:最终决策的学习者
学习者充当该协议的复制因素

image.png

Paxos算法描述

Proposer提案生成算法

  1. Proposer选择一个新的提案编号N,然后向某个Acceptor集合(半数以上)发送请求,要求该集合中的每个
    Acceptor做出如下响应(response)
    (a) Acceptor向Proposer承诺保证不再接受任何编号小于N的提案。
    (b) 如果Acceptor已经接受过提案,那么就向Proposer反馈已经接受过的编号小于N的,但为最大编号的提案的值。
    我们将该请求称为编号为N的Prepare请求。
  2. 如果Proposer收到了半数以上的Acceptor的响应,那么它就可以生成编号为N,Value为V的提案[N,V]。这里的V是所有的响应中编号最大的提案的Value。如果所有的响应中都没有提案,那 么此时V就可以由Proposer自己选择。
    生成提案后,Proposer将该提案发送给半数以上的Acceptor集合,并期望这些Acceptor能接受该提案。我们称该请求为Accept请求。
    Paxos算法分为两个阶段。具体如下:
    image.png

    阶段一:
    (a) Proposer选择一个提案编号N,然后向半数以上的Acceptor发送编号为N的Prepare请求。
    (b) 如果一个Acceptor收到一个编号为N的Prepare请求,且N大于该Acceptor已经响应过的所有Prepare请求的编号,那么它就会将它已经接受过的编号最大的提案(如果有的话)作为响应反馈给Proposer,同时该Acceptor承诺不再接受任何编号小于N的提案。
    阶段二:
    (a) 如果Proposer收到半数以上Acceptor对其发出的编号为N的Prepare请求的响应,那么它就会发送一个针对
    [N,V]提案的Accept请求给半数以上的Acceptor。注意:V就是收到的响应中编号最大的提案的value,如果响应中不包含任何提案,那么V就由Proposer自己决定。
    (b) 如果Acceptor收到一个针对编号为N的提案的Accept请求,只要该Acceptor没有对编号大于N的Prepare请求做出过响应,它就接受该提案。

什么是Raft 算法

首先说什么是 Raft 算法,Raft最初是一种为了管理复制日志的一致性算法。
Raft提供了和Paxos算法相同的功能和性能,但是它的算法结构和Paxos不同。Raft算法更加容易理解并且更容易在实际的系统中应用。
Raft将一致性算法分解成了领导人选举,日志复制,和安全三个模块。

Raft的领导人Leader选举

了解领导人的选举过程,先了解Raft中的节点角色分类,在Raft中,在Raft中,任何时候一个节点服务器都可以扮演下面的角色之一:
领导者(leader):处理客户端交互,日志复制等动作,一般一次只有一个领导者。
候选者(candidate):候选者就是在选举过程中提名自己的实体,一旦选举成功,则成为领导者。
跟随者(follower):类似选民,完全被动的角色,这样的服务器等待被通知投票。
而选举的时候,每个服务器有一个定时器,超时(通常是150—300ms)就重新开启一次选举,选举提交的数据包含了当前的状态轮次和投票的服务器ID(类似map的key和value),领导者会向跟随者节点发送心态和同步日志。如果领导者挂掉,其他的节点变成候选者角色,重新选举领导者,如此往复。当跟随者节点挂掉,会直接剔除该节点,直到该节点恢复后又变成跟随节点并同步当前的轮次信息和日志。

Raft的日志复制(保证数据一致性)

Leader选出后,就开始接收客户端的请求。Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器发起 AppendEntries RPC复制日志条目。当这条日志被复制到大多数服务器上,Leader将这条日志应用到它的状态机并向客户端返回执行结果。
一个典型的复制过程如下图所示:


image.png

1)首先客户端的每一个请求都包含被复制状态机执行的指令。
2)leader把这个指令作为一条新的日志条目添加到日志中,然后并行发起 RPC 给其他的服务器,让他们复制这条信息。
3)跟随者响应ACK,如果 follower 宕机或者运行缓慢或者丢包,leader会不断的重试,直到所有的 follower 最终都复制了所有的日志条目。
4)通知所有的Follower提交日志,同时领导人提交这条日志到自己的状态机中,并返回给客户端。
可以看到,直到第四步骤,整个事务才会达成。中间任何一个步骤发生故障,都不会影响日志一致性。

你可能感兴趣的:(分布式一致性算法Paxos和Raft)