Raft/Leader-Election
选举发生
若Follower在指定超时时间内没有收到Leader发送的HeartBeat,则节点状态由Follower转为Candidate.
并开始进行选举.算法
投票
- CurrentTerm增长1(表示进入下一任期)
- 向自身节点投票
- 设定随机超时时间(ElectionTimeOut -- 2*ElectionTimeOut)
- 向集群中每个节点发送VoteRequest
- 参数 :
- CurrentTerm : 当前Server CurrentTerm值
- Name : 当前Server名称
- LastLogIndex : Log中最新Index值
- LastLogTerm : Log中最新Term值
处理投票请求
- 判断请求参数Term :
- 若是Req.Term小于Self.Term,拒绝请求并发送Self.Term
- 若是Req.Term大于Self.Term,更新Self.Term并将节点状态转为Follower
- 若是Req.Term等于Self.Term且已经接受过投票,拒绝请求并发送Self.Term
- 判断LastLogIndex,LastLogTerm :
- 若是Self.LastLogIndex 或者 Self.LastLogTerm 大于 Req中相应的值,则拒绝该请求
- 成功投票:
- 流程分析 :
- 判断Term :
- Term为Raft算法中的逻辑时钟.做为某些在同一周期内只能发生一次的行为的判断依据.
- 若是Req.Term大于Self.Term,说明本节点周期落后于系统(新加入集群,Crash后恢复,落后节点等状况)
- 若是Req.Term小于Self.Term,说明请求节点周期落后于系统,则拒绝请求
- 在相同Term周期中,投票行为只能发生一次
- 判断LastLogIndex,LastLogTerm :
- 拒绝投票给Log落后于本节点的节点请求,从而保证选出的Leader拥有最完整的数据
- 由于提交数据须要得到大多数节点的认可,因此落后节点的投票请求会被大多数节点所拒绝,从而保证了Leader必定拥有完整数据.
选举结束
- 得到大多数节点赞成 : 节点状态从Candidate变为Leader
- 收到AppendEntriesRequest(心跳) : 若是Req.CurrentTerm大于等于Self.CurrentTerm.则节点变为Follower,退出选举.
- 超时 : Self.CurrentTerm增长一.从新开始选举