声明:本系列文章面向的读者需要看过Raft论文或者对Raft有一定的了解,如果没有看过论文或者不了解Raft,建议先去学习后再来看,否则会比较难懂。
紧接着上一篇的内容,继续探索Raft的leader选举、日志复制、安全性等等实现细节。
Raft基础
一个Raft集群通常包含多个机器,比较普遍的Raft集群组成是2F+1,F代表的是可以发生失败的机器数量。比如集群有5台机器,那么Raft只能容忍两台服务失败,如果三台服务不能工作了,那么整个集群也就失败了。大多数Raft集群的机器数量都是5个。
每台机器都有三个状态:leader、follower、candidate,如下图所示,就是三种状态之间的转换图。
leader接收所有的请求,如果client请求到了follower,那么follower会将请求转发到leader
follower只是接收来自leader和candidate的请求,不会主动发起请求。
如果follower没有收到任何通信或信号,转变为candidate,然后重新进行一轮新的选举
candidate,是在选举新leader时出现的状态,如果candidate收到来自大多数机器的投票请求(RequestVote RPC,以下称为RequestVote请求),就会转变为leader
Raft把时间按照term划分,每个term以一次选举开始,如果某一个candidate成为新的leader后,就进入正常运行阶段,如果没有选举出新的leader,那么就再次进行一次新的选举,这时候又是一个新的term。简单地说,在Raft中,是以term做时间单位。如下图所示:
每一个服务器都会保存当前的term序号,当前的term序号会在服务器通信之间传递。如果服务器收到的请求包含了旧的term,服务器会拒绝该请求。
leader选举
再来看看Raft是如何进行leader选举的,Raft使用心跳机制来触发leader选举。当服务器启动的时候,初始状态是follower,leader发送心跳的方式是发起一个不包含日志条目的AppendEntries RPC(以下称为Append请求)到所有的follower,follower收到来自leader的心跳请求包,说明leader还在”存活”着,如果长时间没有收到leader的心跳,那么follower就会认为当前没有leader,转为candidate,然后发起一次新的leader选举。
当leader选举开始时,follower会将当前的term自增,随后马上进入candidate状态,并发起一次RequestVote请求到所有机器,请求其他机器对它进行投票。Raft集群中的服务器在一个term里,除了投给自己之外,只能投票给一个candidate。
如果有以下三种情况发生,candidate的状态就会发生转变:
1、candidate获得大多数服务器的投票,成为leader,此时leader会马上发出心跳消息包,通知其他机器它成为了leader
2、candidate收到来自其他机器的心跳消息包,且该心跳包含的term大于当前candidate的term,说明已经有新的leader产生,candidate转为follwoer。(如果心跳包含的term小于当前candidat