# Raft Leader 选举

__*Leader 选举*__
__*term*__
__*有效消息*__

![left](./student-guide/diagram/RaftLeaderElect01_aa_001_20220511.png)
-------------------------------------------------------------
下面,我们描述 Leader 选举:

一开始,我们先介绍一个概念叫:term,所谓 term 就是 Raft  共识算法将时间分成的小段（ 也可以理解为在 Raft 共识算法眼中,时间被分为了一个 term 接着一个 term ）,每个 term 的大小可能是不一样的,我们用连续递增的数字来标识这些 term ,保存在每个节点中,在 term 的初始阶段一定是选举阶段,当 leader 诞生之后,这个 term 的剩余时间里整个 raft 集群对外提供正常的服务,如果没有发生异常,这个 term 将一直持续下去（ term 的标识不会发生改变 ）,如果发生异常（比如 leader 宕机或者网络问题）,那么当前 term 将结束,新的节点会递增之前的 term 标识,然后进行新一轮的选举。这里我们还要注意一点,Raft 是要保证在一个 term 内,最多只有一个 leader 在集群中。

那么,何时会发起选举呢？

集群初始时,所有节点都是 follower,当 follower 在指定的时间之内没有收到 leader 或者 candidate 的有效消息时会发起选举。这个指定的时间被称为 election timeout,是一个随机的值（比如默认是 10s ）。什么是有效消息 ？leader 的有效消息是指心跳消息,candidate 的有效消息是指投票消息。这里引入了两个状态变量,election timeout 和 heartbeat time interval ( leader 发送心跳间隔时间 ),要求 heartbeat time interval 小于 min(election timeout),避免 follower 重新发起无谓的投票。

假设,图中节点 2 最先突破了 election timeout,这时候它会先将自己的 term 标识递增,将自己变为 candidate 角色,并且投票给自己。同时,向集群其它机器发起投票请求,请求中包含自己刚刚递增的 term 标识。其他的 follower 收到的投票请求包含的 term 大于等于当前 term 标识会同意,并且更新自己的 term 标识,发送同意信息给 candidate 角色的节点。

这时,candidate 角色的 TiKV 节点收到超过集群一半 TiKV 节点都同意自己为 leader,状态变为leader,并且立即向所有节点发送心跳消息,之后按照心跳间隔时间发送心跳消息。

到此,初次选举就完成了。

