Raft算法原理和解析

与Paxos不同Raft强调的是易懂,Raft和Paxos一样只要保证n/2+1节点正常就能够提供服务;raft把算法流程分为三个子问题:

  • 选举(Leader election)
  • 日志复制(Log replication)
  • 安全性(Safety)
  • 什么是 Raft 算法?Raft 算法是一种简单易懂的共识算法。它依靠状态机 和 主从同步的方式,在各个节点之间实现数据的一致性。
  • Raft的两个核心要点:
  • 1.选取主节点
  • 2.同步数据不难理解,使用主从同步的方式,可以让集群各个节点的数据更新以主节点为准,从而保证了一致性。
    那么,如何选取主节点呢?Raft算法在选择主节点的过程中,也是通过多个节点之间的投票竞争。说到这里,不得不说一下Raft算法的状态机。
  • Raft算法为节点定义了三种角色
  • 1.Leader(主节点):领导者-日志管理
    负责日志的同步管理,处理来自客户端的请求,与Follower保持着heartBeat的联系。
  • 2.Follower(从节点):追随者-日志同步
    刚启动时候所有节点为Follower状态,响应Leader的日志同步请求,响应Candidate请求,把请求到Follower的事务转发给Leader
  • 3.Candidate(参与投票竞争的节点):候选者-负责选票
    负责选举投票,Raft刚启动时候由一个节点从Follower转为Candidate发起选举,选举出Leader后从Candidate转为Leader状态。
  • 任期(Term)
    在Raft中使用了一个可以理解为周期(第几届、任期)的概念,用Term作为一个周期,每个Term都是一个连续递增的编号,每一轮选举都是一个Term周期,在一个Term中只能产生一个Leader;当某个节点收到的请求中Term比当前Term小时候则拒绝该请求。
  • 选举(Election)
    Raft 的选举由定时器来触发,每个节点的选举定时器时间都是不一样的,开始时状态都为Follower 某个节点定时器触发选举后 Term 递增,状态由 Follower 转为 Candidate ,向其他节点发起 RequestVote RPC 请求,这时候有三种可能的情况发生:
    1:该RequestVote 请求接收到 n/2+1 (过半数)个节点的投票,从Candidate 转为 Leader,向其他节点发送 heartBeat 以保持 Leader 的正常运转。
    2 :在此期间如果收到其他节点发送过来的AppendEntries RPC 请求,如该节点的 Term 大则当前节点转为 Follower,否则保持Candidate 拒绝该请求。
    3 :Election timeout 发生则 Term 递增,重新发起选举
    在一个 Term 期间每个节点只能投票一次,所以当有多个 Candidate 存在时就会出现每个Candidate 发起的选举都存在接收到的投票数都不过半的问题,这时每个 Candidate 都将 Term递增、重启定时器并重新发起选举,由于每个节点中定时器的时间都是随机的,所以就不会多次存在有多个 Candidate 同时发起投票的问题。
    在 Raft 中当接收到客户端的日志(事务请求)后先把该日志追加到本地的 Log 中,然后通过heartbeat 把该 Entry 同步给其他 Follower,Follower 接收到日志后记录日志然后向 Leader 发送ACK ,当 Leader 收到大多数(n/2+1)Follower 的 ACK 信息后将该日志设置为已提交并追加到本地磁盘中,通知客户端并在下个 heartbeat 中 Leader 将通知所有的 Follower 将该日志存储在自己的本地磁盘中。
  • 安全性(Safety)
    安全性是用于保证每个节点都执行相同序列的安全机制如当某个 Follower 在当前 Leader commitLog 时变得不可用了,稍后可能该 Follower 又会倍选举为 Leader,这时新Leader 可能会用新的Log 覆盖先前已 committed 的 Log,这就是导致节点执行不同序列;Safety 就是用于保证选举出来的 Leader 一定包含先前 commited Log 的机制;
    选举安全性(Election Safety):每个 Term 只能选举出一个 Leader
    Leader 完整性(Leader Completeness):这里所说的完整性是指 Leader 日志的完整性, Raft 在选举阶段就使用 Term 的判断用于保证完整性:当请求投票的该 Candidate 的 Term 较大 或 Term 相同 Index 更大则投票,该节点将容易变成leader。
  • Raft 算法选主的具体流程:
    第一步,在最初,还没有一个主节点的时候,所有节点的身份都是Follower。每一个节点都有自己的计时器,当计时达到了超时时间(Election Timeout),该节点会转变为Candidate。
    在这里插入图片描述
    第二步,成为Candidate的节点,会首先给自己投票,然后向集群中其他所有的节点发起请求,要求大家都给自己投票。
    在这里插入图片描述
    第三步,其他收到投票请求且还未投票的Follower节点会向发起者投票,发起者收到反馈通知后,票数增加。
    在这里插入图片描述
    第四步,当得票数超过了集群节点数量的一半,该节点晋升为Leader节点。Leader节点会立刻向其他节点发出通知,告诉大家自己才是老大。收到通知的节点全部变为Follower,并且各自的计时器清零
    在这里插入图片描述
    这里需要说明一点,每个节点的超时时间都是不一样的。比如A节点的超时时间是3秒,B节点的超时时间是5秒,C节点的超时时间是4秒。这样一来,A节点将会最先发起投票请求,而不是所有节点同时发起。为什么这样设计呢?设想如果所有节点同时发起投票,必然会导致大家的票数差不多,形成僵局,谁也当不成老大。那么,成为Leader的节点是否就坐稳了老大的位置呢?并不是。Leader节点需要每隔一段时间向集群其他节点发送心跳通知,表明你们的老大还活着。
    一旦Leader节点挂掉,发不出通知,那么计时达到了超时时间的Follower节点会转变为Candidate节点,发起选主投票,周而复始…
    在这里插入图片描述
  • Raft 算法数据同步流程:
    第一步,由客户端提交数据到Leader节点。
    在这里插入图片描述
    第二步,由Leader节点把数据复制到集群内所有的Follower节点。如果一次复制失败,会不断进行重试。在这里插入图片描述
    第三步,Follower节点们接收到复制的数据,会反馈给Leader节点。
    在这里插入图片描述
    第四步,如果Leader节点接收到超过半数的Follower反馈,表明复制成功。于是提交自己的数据,并通知客户端数据提交成功。
    在这里插入图片描述
    第五步,由Leader节点通知集群内所有的Follower节点提交数据,从而完成数据同步流程。
    在这里插入图片描述

你可能感兴趣的:(职场@分布式服务)