首页 > 代码库 > Raft算法

Raft算法

转:http://feixiao.github.io/

Raft是什么?

  • 一致性算法允许一组机器像一个整体一样工作,即使其中一些机器出现故障也能够继续工作下去。
  • 一致性算法是从复制状态机的背景下提出的。在这种方法中,一组服务器上的状态机产生相同状态的副本,并且在一些机器宕掉的情况下也可以继续运行。复制状态机在分布式系统中被用于解决很多容错的问题。
  • Raft 是一种为了管理复制日志的一致性算法。

    Raft 一致性算法

  • Raft 通过选举一个高贵的领导人,然后给予他全部的管理复制日志的责任来实现一致性。领导人从客户端接收日志条目,把日志条目复制到其他服务器上,并且当保证安全性的时候告诉其他的服务器应用日志条目到他们的状态机中。拥有一个领导人大大简化了对复制日志的管理。
  • 通过领导人的方式,Raft 将一致性问题分解成了三个相对独立的子问题。
    • 领导选举:一个新的领导人需要被选举出来,当先存的领导人宕机的时候
    • 日志复制:领导人必须从客户端接收日志然后复制到集群中的其他节点,并且强制要求其他节点的日志保持和自己相同。
    • 安全性:如果有任何的服务器节点已经应用了一个确定的日志条目到它的状态机中,那么其他服务器节点不能在同一个日志索引位置应用一个不同的指令。(???怎么理解?)

Raft 基础

  • 一个 Raft 集群包含若干个服务器节点;通常是5个,这允许整个系统容忍2个节点的失效。在任何时刻,每一个服务器节点都处于这三个状态之一:领导人、跟随者或者候选人。
  • 领导人处理所有的客户端请求(如果一个客户端和跟随者联系,那么跟随者会把请求重定向给领导人)。跟随者只响应来自其他服务器的请求。如果跟随者接收不到消息,那么他就会变成候选人并发起一次选举。获得集群中大多数选票的候选人将成为领导者。领导人一直都会是领导人直到自己宕机了。
  • Raft算法中服务器节点之间通信使用远程过程调用(RPCs),并且基本的一致性算法只需要两种类型的 RPCs。
    • 请求投票(RequestVote):RPCs 由候选人在选举期间发起。
    • 附加条目(AppendEntries):RPCs 由领导人发起,用来复制日志和提供一种心跳机制。

      领导人选举

  • Raft 使用一种心跳机制来触发领导人选举。当服务器程序启动时,他们都是跟随者身份。一个服务器节点要想继续保持着跟随者状态除非他从领导人或者候选者处接收到有效的 RPCs。
  • 如果一个跟随者在一段时间里没有接收到任何消息,也就是选举超时,然后他就会认为系统中没有可用的领导者然后开始进行选举以选出新的领导者。
  • 要开始一次选举过程,跟随者先要增加自己的当前任期号并且转换到候选人状态。然后他会并行的向集群中的其他服务器节点发送请求投票的 RPCs 来给自己投票。候选人会继续保持着当前状态直到以下三件事情之一发生:
    • (a) 他自己赢得了这次的选举。
    • (b) 其他的服务器成为领导者。
    • (c) 一段时间之后没有任何一个获胜的人。
  • 当一个候选人从整个集群的大多数服务器节点获得了针对同一个任期号的选票,那么他就赢得了这次选举并成为领导人。每一个服务器最多会对一个任期号投出一张选票,投票的限制条件是?
    • 选举限制
      • Raft使用投票的方式来阻止候选人赢得选举除非这个候选人包含了所有已经提交的日志条目。
      • 候选人为了赢得选举必须联系集群中的大部分节点,这意味着每一个已经提交的日志条目肯定在这些服务器节点中至少存在一个上面。如果候选人的日志至少和大多数的服务器节点一样新(这个新的定义会在下面讨论),那么他一定持有了所有已经提交的日志条目。
        • 请求投票RPC实现了这样的限制: RPC中包含了候选人的日志信息,然后投票人会拒绝掉那些日志没有自己新的投票请求。
        • Raft 通过比较两份日志中最后一条日志条目的索引值和任期号定义谁的日志比较新。如果两份日志最后的条目的任期号不同,那么任期号大的日志更加新。如果两份日志最后的条目任期号相同,那么日志比较长的那个就更加新。
  • 一旦候选人赢得选举,他就立即成为领导人。然后他会向其他的服务器发送心跳消息来建立自己的权威并且阻止新的领导人的产生。

    日志复制

  • 领导人被选举出来之后,他就开始为客户端提供服务。客户端的每一个请求都包含一条被复制状态机执行的指令。领导人把这条指令作为一条新的日志条目附加到日志中去,然后并行的发起附加条目RPCs 给其他的服务器,让他们复制这条日志条目。当这条日志条目被安全的复制,领导人会应用这条日志条目到它的状态机中然后把执行的结果返回给客户端。如果跟随者崩溃或者运行缓慢,再或者网络丢包,领导人会不断的重复尝试附加日志条目 RPCs (尽管已经回复了客户端??什么时候返回的?)直到所有的跟随者都最终存储了所有的日志条目。
  • 日志格式
    技术分享
    日志由有序的序号标记的条目组成。每个条目都包含创建时的任期号(图中框中的数字)和一个状态机需要执行的指令。
  • 领导人来决定什么时候把日志条目应用到状态机中是安全的;这种日志条目被称为已提交。Raft算法保证所有已提交的日志条目都是持久化的并且最终会被所有可用的状态机执行。在领导人将创建的日志条目复制到大多数的服务器上的时候,日志条目就会被提交。同时,领导人的日志中之前的所有日志条目也都会被提交,包括由其他领导人创建的条目。
  • Raft通过计算副本数目的方式,使得永远不会提交一个之前任期内的日志条目??
    • how ?

跟随者和候选人崩溃

  • 如果跟随者或者候选人崩溃了,那么后续发送给他们的 RPCs 都会失败。Raft中处理这种失败就是简单的通过无限的重试;如果崩溃的机器重启了,那么这些RPC就会完整的成功。如果一个服务器在完成了一个RPC,但是还没有响应的时候崩溃了,那么在他重新启动之后就会再次收到同样的请求。Raft 的 RPCs 都是幂等的,所以这样重试不会造成任何问题。

参考资料

    • 《Raft动画演示》
    • 《寻找一种易于理解的一致性算法(扩展版)》
    • 《Raft实验》

Raft算法