raft算法

一、raft角色和消息

raft协议中包含三个角色 :跟随者(follower)、领导者(leader)和候选者(candidate)。有三种消息:投票请求、心跳数据和日志复制,

  1. 三种角色的作用
    1. 跟随着:存放数据副本。
    2. 领导者:对外提供写服务。
    3. 候选者:竞争领导者。
  2. 三种消息作用
    1. 投票请求:候选者发给其他人,拉票成为领导者。
    2. 心跳包:领导者证明自己活着。
    3. 日志复制:领导者修改日志,将消息发送给跟随着,保证数据的一致性。

说到底,raft三种角色就是一台机器的三个状态,通过消息传递状态发生改变,从而维护数据的一致性以及对外服务的可用性。

二、对数据的不同应答

    三种角色在各自的状态时都有可能收到任意一种消息,那三种角色如何对消息作出反映。

2.1 跟随着

2.1.1 收到投票请求

    跟随者收到别人发来的投票请求,这个请求的term,要么比自己大,要么和自己一样,要么比自己小。

第一种情况:还没有投过票

    如果请求的term比自己大,并不能直接说明leader已经宕机了,这里依然需要判断对方的最后一条日志的term和在其日志序列的index。

    第一种情况:如果对方的log.LastTerm比follower大,可能因为这个follower宕机有活过来了,此时恰逢选举,那么follower保留的还是以前的term,所以会无条件跟随这个候选人,于是就把自己的term调整到和对方一样,并投出赞成票,同时还要重置自己的选举计时器。

    第二种情况:log.LastTerm和自己一样,那么就比较log.LastIndex,如果比自己大,可能自己在任期内宕机重启,或者,自己根本没收到leader的日志复制请求,结果leader就宕机了。不管那样,总之要赞成对方。

    第三种情况:对方的log.LastIndex比自己小或者log.LastTerm比自己小,这就说明对方可能宕机重启,然后超时尝试选举,此时follower会将自己的term返回给对方,并且拒绝对方的选举请求。

第二种情况:已经投过票

    第一种情况:如果对方的log.LastTerm比follower大或者term一样log.LastIndex大,可能因为这个follower宕机有活过来了,此时恰逢选举,结果有一个也宕过机的,他天给这个follower发送了投票请求,然后拥有最新的term cnadidate有发送了投票请求,此时term大,所以跟随。将自己的term改为和对方一样。

    第二种情况:log.LastTerm和自己一样,log.LastIndex也和自己一样,说明有多个竞选者,但是已经投给第一个了,所以会拒绝第二个候选者的请求。

    第三种情况:对方的log.LastIndex比自己小或者log.LastTerm比自己小,这种情况直接拒绝。

2.1.2 收到心跳数据

    收到心跳数据也需要比较term大小。这里心跳包和日志复制包其实可以采用一种消息格式,但是为了说明状态不变化也单独拎出来了。

    第一种情况:如果心跳数据的term比自己大,可能有候选者成为了leader,自己没有参与对方选举投票,那个选举者获得了其他多数派的赞成票。此时follower则将自己的term调成和leader一致回复收到,并且重置自己的定时器。

    第二种情况:如果心跳数据的term等于自己的term,说明一切都很正常,重置定时器,回复收到。

    第三种情况:如果心跳数据比自己小,可能是因为集群脑裂后又恢复,此时,follower回将自己的term回复,并回复false。

2.1.3 收到日志复制

    日志复制的term关系和心跳数据一样的,这里就来分析日志复制是的匹配问题。

    第一种情况:如果leader的日志复制索引和任期与自己的完全一致,那么就将日志添加近来,并且同步与leader提交日志的索引。

    第二种情况:如果leader的日志复制索引和任期与自己的不一致,那只会有按照leader进行恢复,要么自己的日志比leader的多,就删除多余的日志,如果自己的的日志比leader的少,就请求新的log日志,无论怎样,非常重要的一点是:follower的日志必须和leader的同步,并且,follower的日志commit的部分一定不会比leader多。

2.2 候选者

2.2.1 收到投票请求

    候选者收到投票请求也需要分开讨论,但不一样的是,follower一定是投出过选票的人,并且投的是自己。

    第一种情况:如果对方的log.LastTerm比candidate大,或者log.LastTerm和自己一样log.LastIndex比自己大,意味着有更新的candidate,所以次candidate需要将身份变为follower,并且调整自己的term和对方的term一致,投出赞成票,重置自己的竞选计时器。

    第二种情况:log.LastTerm和log.LastIndex都和自己一样,那么candidate已经投给自己,所以u会拒绝对方的投票请求。

    第三种情况:对方的log.LastIndex比自己小或者log.LastTerm比自己小,拒绝对方的请求,回复自己的term。

2.2.2 收到心跳数据

    第一种情况:如果对方的log.LastTerm比candidate大,或者log.LastTerm和自己一样log.LastIndex比自己大,意味着有新的leader已经出现,此时变为follower,调整自己的term,重置定时器。

    第二种情况:log.LastTerm和log.LastIndex都和自己一样,此时已经有leader产生,不需要在继续竞争leader,这个系统已经稳定了,不要通过竞争扰乱稳定。所以变为follower,重置竞选定时器。

    第三种情况:对方的log.LastIndex比自己小或者log.LastTerm比自己小,拒绝对方的请求,回复自己的term,继续竞争leader。

2.2.2 收到日志复制

    情况和心跳数据一样的,这里对于日志的复制行为也和跟随者一样。如果认同对方的leader身份,进行日志匹配,否则拒绝对方并恢复自己的term。

2.3 领导者

2.3.1 收到投票请求

    领导者收到投票请求也不需要考虑有没有投过票,领导者必然每个任何人投过赞同票。

    第一种情况:如果对方的log.LastTerm比自己大,那么自身变为follower,同意选票。

    第二种情况:log.LastTerm和自己一样,无论log.LastIndex比自己大或者比自己小,自己已经成为了leader,另一个候选者不可能再拿到多数人的同一,因为自己已经当选leader,说明大多数follower已经投过自己,而由于这个候选者term一样,follower已经透过选票,即使他的log.LastIndex大,也没有用了。

    第三种情况:对方的log.LastTerm比自己小,拒绝对方的请求,回复自己的term。

2.2.2 收到心跳数据

    第一种情况:如果对方的log.LastTerm比自己大,变为follower,调整自己的term,重置定时器。

    第二种情况:log.LastTerm自己一样,根本不可能出现,因为同一个集群,每个leader的号码都是不一样的,即使分区,也不可能出现号码一样的两个leader。

    第三种情况:对方的log.LastIndex比自己小,拒绝对方的请求,回复自己的term,继续当leader。

2.2.2 收到日志复制

    情况和心跳数据一样的,这里leader如果角色不变化,是不会检查自己的日志,如果角色发生变化才会检查自己的日志。

三、收到应答的变化

    无论哪种角色,不仅收到请求数据可能引起状态改变,当他请求别人,别人应答时,自身也会根据别人的应答改变身份。

    基本变化都很简单,只要对方的term比自己的大,自己就会变为follower,跟随对方的term。只有候选者,如果得到了大多数人的赞同,就会成为leader。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值