领导选举 —> 状态复制
- 领导选举
每个节点可以有三个身份,分别是跟随者,候选者和领导者。
当节点是跟随者时,它并没有收到领导者的消息,那它就可以变成候选者。接下来,成为候选者的节点会请求其他节点给自己发来选票,其他节点收到请求以后会回复它。如果某个候选者收到绝大多数节点的投票,那它就变成领导者。
- 状态复制
当一个节点被选为领导者时,所有系统中的变化都会经由领导者处理。客户端每一个数据变化都会首先新增到领导者的日志中,并且将当前数据设置为未提交
状态。接下来,领导者将数据复制传给各个跟随者节点,领导者会一直等待直到大多数节点已经将数据写入了(写入后会回复领导者表示已经收到了)。此时领导者就可以将当前状态设为已提交
,并且通知所有跟随者当前数据已提交了。领导者发送消息告诉客户端,此时达到了分布式共识。
- 协议细节:
- 选举过程:
1)选举timeout设置:跟随者会等待一段时间直到变成候选者,这段时间随机设定为150ms至300ms(每个节点随机)。当时间结束后,跟随者变为候选者,并且开始新的任期term
。接下来成为候选者的节点就会发送RequetVote
消息给其他节点(自己也会投给自己一票),如果收到消息的其他节点没有投过票,那它就为这个候选者投票。节点投完票之后就会重置自己选举倒计时。换句话说,每个节点为自己计时,当倒计时结束时,就认可自己是候选者,一旦有一个候选者拥有了大多数的票数,那它就变成了领导者。
领导者开始发送Append Entries
信息给跟随者节点们,这些消息按照heartbeat
倒计时规定的时间间隔发送,然后跟随着会回复每个Append Entries。当有一个跟随者节点停止接受心跳包并且变成候选者时,这次选举任期会结束。
2)如果两个节点同时变成了候选者,就会出现分裂投票,即两个节点票数相等。此时会重新等待新的候选者成为领导者。
- 状态复制过程
1)一旦我们选出了领导者,我们就需要将系统的所有更改复制到所有节点,这通过使用Append Entries作为心跳包完成。
2)当出现网络分区时,可能会出现多个领导者。当某个领导者看到更大的任期数字时它会下台。由于无法收到大多数跟随者节点的确认,某个领导者会将状态设为未提交
,因此会回滚其未提交的条目,并且匹配新领导的日志。