理解raft(1) 选举

任期 Term

Raft把时间分割成任意长度的任期,任期用连续的整数标记。每一段任期从一次选举开始。

term是一个逻辑时钟,因此,当一台机器在与其他机器通信时发现自己的term比较小,应该推进本地的term。如果一台机器发现请求方的term比较小,则要拒绝请求。如果一个candidate发现自己的term落后了,就要退回到follower。

1554194844589.png

Raft协议的每个副本都会处于三种状态之一:

  1. Leader:处理所有的client请求,本地处理后同步至其他副本

  2. Follower:被动的更新者

  3. Candidate:Follower副本在一段时间内没有收到leader副本的心跳,则判断leader可能已经故障,此时启动选主过程,follower变为candidate状态。

选举过程

参与选举

每个term一开始就进行选主:

Follower将自己的current_term_id + 1(需要持久化),并转换自己称为Candidate

发送RequestVoteRPC给其他所有的server。

Candidate状态持续到以下三种情况发生

  • a) 该candidate赢得了选主

  • b) 其他机器成为了leader

  • c) 超时间内未能选主成功

一个candidate赢得选主的判定:在相同的term内,收到了多数派的投票。

选主成功之后,新主向其他主机发送心跳AppendEntries RPC,宣告自己当选了。

在选主时间内, candidate如果收到了其他主机宣告当选的心跳AppendEntries RPC且RPC中携带的term比本机维护的term更大或相等,本机就自动退为follower。

若在一个term内选主失败时,所有candidate递增term开始下一轮。为了减少选票分裂出现的概率,选举超时时间使用随机化的方法避开多个candidate同时拉票。

投票机制

raft确保leader是当前多数派中拥有最新日志的节点, 以此来确保日志流只从leader流向follower而无需从

不落后的follower拉去日志。

首先,在给定的term内,每台机器都只能按照先来先服务的规则投一个candidate(要持久化)。

其次,保证包含所有commit日志的candidate才能有机会被选为leader。因为一条日志commit,必然在任意一个多数派中,至少有一台主机包含了这条日志。选举时,candidate要和至少多数派的主机通信,通信时带上自己本地的日志信息(本地最后一条的term和log id),接收消息的主机发现发送消息的candidate的日志并不比我本地更新,就拒绝投票。也就是说,candidate至少是某个多数派中拥有最新日志的主机,才能被选为leader。

你可能感兴趣的:(理解raft(1) 选举)