分布式理论Paxos, Raft

一、Paxos算法

世界上只有一种一致性算法,就是 Paxos,其它的算法都是残次品,但Paxos非常复杂难懂。

算法原理参考:Paxos的通俗解释 Paxos共识算法详解

算法例子参考:如何浅显易懂地解说 Paxos 的算法?

Paxos算法的核心问题是:解决分布式系统的一致性的问题,所有问题均围绕着在分布式环境达成一致性而展开讨论的。

预备知识

术语

  • proposer:提案者,它可以提出一个提案。
  • acceptor:提案的受理者,有权决定是否它本身是否批准该提案。
  • learner:不参与Paxos提案选定的过程,只在提案被选定时,知道提案结果的角色。
  • proposal:由Proposer 提出的提案,每个提案由编号及value组成,如[m, value],提案的编号必须是全局唯一,value即代表了提案本身的内容。
  • choose:提案被选定,当有半数以上Acceptor批准该提案时,就认为该提案被选定了。

提案编号

有专门的编号生成算法,只需要知道它是全局唯一且递增的就行了,就是说越新的提案,编号越大。

通信条件

  • 系统所有消息均存在延迟、丢失、重复的可能,系统也可以随时会重启。
  • 系统所有的消息不存篡改的问题,也即不存在拜占庭的问题。

算法过程

跳过复杂的推理过程,直接给出算法过程。

Learner不参与投票过程,为了简化描述,我们直接忽略掉这个角色。

算法分为两个阶段执行。

扫描二维码关注公众号,回复: 8619543 查看本文章

阶段1.

  1. proposer:选择一个提案编号Mn,向超过半数的acceptor发送编号为Mn的prepare请求
  2. acceptor:如果接收到编号为Mn 的prepare请求,并且Mn大于它已经回应的任何prepare请求,它就回复Promise响应,返回已经批准的编号最高的提案的value(如果有的话),并承诺不再批准任何编号小于Mn的提案。

阶段2.

  1. proposer
    • 如果收到了多数acceptor对prepare请求Mn的回应,它就向这些Acceptor发送提案[Mn, Mv]的accept请求,其中Mn的值为:
      1. 响应带回了其他的已批准的提案,所有prepare请求响应中编号最大的已批准提案的value(相当于放弃自己的提案,变成复读机)。
      2. 响应没有带回其他的已批准的提案:proposer 自己选择的value(相当于还没有其他提案被批准过,该proposer获得first blood)。
    • 没有收到多数acceptor对prepare请求Mn的回应:回到第一步重新发起提案。
  2. acceptor:如果收到了提案[Mn, Mv]的accept请求,它就回复accepted响应,批准该提案,除非它已经回应了一个编号大于Mn的提案。

算法过程图示

clipboard.png

可见Acceptor需要持久化存储minProposal、acceptedProposal、acceptedValue这3个值。

proposer 可以提出多个提案,只要它遵循上面的算法。它可以在任何时刻放弃一个提案。(这不会破坏正确性,即使在提案被放弃后提案的请求或者回应消息才到达目标)如果其它的proposer 已经开始提出更高编号的提案,那么最好能放弃当前的提案。

二、Raft算法

参考分布式理论(六)——-Raft-算法

Raft 也是一个一致性算法,且比起Paxos更容易理解。就是说Paxos虽然在学术界是最强的,但是难理解、难实现,所以工业界广泛使用的还是Raft算法。

Raft主要有两个模块:领导人选举和日志复制。

领导人选举

Raft 通过选举一个领导人,然后给予他全部的管理复制日志的责任来实现一致性。

每个节点可以在三个身份之间切换:Leader、candidate、follower。

刚开始时所有节点都是follower,这个时候需要选举一个 leader,所有人都变成candidate,直到有人成功当选 leader,这些落选的candidate又变回follower。角色轮换图如下:

角色变化图

其中,leader也有可能会宕机,就需要引发新的选举,所以整个集群在选举和正常运行之间切换,具体如下图:

image.png

可以注意到, 上图中的 term 3 选举之后没有跟着正常运行阶段,这是因为当一次选举失败(比如正巧每个节点都投了自己)后,就需要再重新选举,每个节点会在一个随机的时间里重新投票,这样就能保证不冲突了。所以,当 term 3 选举失败,等了几十毫秒,执行 term 4 选举,并成功选举出leader。

接着,leader周期性的向所有follower发送心跳包来维持自己的权威。如果一个follower在一段时间里没有接收到任何消息,也就是选举超时,那么他就会认为系统中没有可用的leader或者leader宕机,并且发起选举以选出新的leader。

要开始一次选举过程,follower先要增加自己的当前任期号并且转换到candidate状态。然后请求其他服务器为自己投票。

规则

  1. 每一个 server 最多在一个任期内投出一张选票(有任期号约束),先到先得。
  2. 要求最多只能有一个人赢得选票。
  3. 一旦成功,立即成为领导人,然后广播所有服务器停止投票阻止新得领导产生。

可能会产生 3 种结果:

  1. 自己成功当选
  2. 其他人成为领导者
  3. 所有人票数相同,没有任何一个人成为领导者

遇到第三种情况而僵住时,Raft 通过使用随机选举超时时间(例如 150 - 300 毫秒)的方法将服务器打散投票。每个候选人在僵住的时候会随机从一个时间开始重新选举。

日志复制

一个leader被选举出来后,他就开始为客户端提供服务。

客户端发送日志给leader,随后leader将日志复制到他的follower上。如果follower故障,leader将会尝试重试,直到所有的follower都成功存储了所有日志。

下图表示了当一个客户端发送一个日志给leader,随后leader复制给follower的整个过程。

image.png

4 个步骤:

  1. 客户端提交数据给leader
  2. leader复制数据给所有follower
  3. follower回复 确认接收
  4. leader回复客户端和所有follower 确认提交

直到第4步骤,整个事务才会达成。中间任何一个步骤发生故障,事务都会中止,因此故障不会影响到日志一致性。

与其他算法的区别

  • 2PC 和 3PC都只有一个协调者,宕机之后会使阶段提交无法进行(2PC的参与者会阻塞,3PC的参与者可以继续本地提交)。
  • Paxos有多个accepter,审批proposer的提案。
  • Raft只有一个leader,如果leader宕机,可以重新选举一个leader出来继续工作。
发布了131 篇原创文章 · 获赞 12 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_41519463/article/details/103936685