在分布式系统中,为了提高系统的可用性,达到99.999%的指标,我们通常会对服务节点做集群,采用主从互备的方式增强服务的可用性。在主从互备的集群中,主节点和从节点需要保证数据一致,主节点服务出现问题后,需要在从节点中选举出一个新的主节点,那么常用的分布式选举算法有Bully算法、Raft算法、ZAB算法。本节主要对Raft算法进行分析。
Raft算法原则
遵从少数服从多数的原则,规定在一个周期内得票最多的节点为主节点。
三种角色
Raft算法将集群节点划分为三种角色。
领导人(Leader):即主节点,在一个集群中只能存在一个,用于协调和管理其他节点。
候选人(Candidate):只有候选人才能成为领导人
群众(Follower):跟随领导者,不可以发起选举
可以看出,跟我们实际的选举制度差不多,人大代表类似群众角色,在候选人中间投票,得票多者成为选举获胜者
角色状态转换如下:
选举流程
1、集群初始化时,没有领导人,都是群众
2、集群中的所有节点在没有领导人的情况下,会转换成候选人,转换的过程有快有慢(选举超时控制机制,避免同一时间同时转换,一般在150ms至300ms之间的随机值),图示群众2使用150ms,用时最短
3、候选人2向群众/候选人1、群众/候选人3发送选举的请求,发送的过程中群众1和群众3都有可能已经转换成候选人,因为选举超时机制时间原因(节点收到选举请求有先后)且每个节点在一个选举周期内只能投一票,所以示例候选人2率先发起选举
4、群众/候选人1、群众/候选人3都同意候选人2的选举,那么候选人2的票数大于半数,获得成功
5、候选人2获得半数选票后,会宣布自己的任期(首期为1),其他节点都转换为群众节点,领导人定期发送心跳给群众
选举过程中如果出现平票,任期加1,并重新发起选举
领导人节点如果网络延迟或者死机,群众接收不到心跳包(超时)会重新发起选举(之前任期结束),此时领导人节点降级为群众,参与新一轮选举
数据同步
集群中出现领导人节点后,客户端写入操作就会针对领导人节点展开,领导人节点再同步信息给群众节点完成最终值的修改。
1、客户端将更新数据发送给领导人节点,领导者节点会在本地建立日志条目,记录这次修改。
2、领导者节点将这个日志条目信息同步给所有的群众节点。
3、群众节点收到日志条目信息后,会向领导者节点发送确认信息。领导者节点收到群众节点返回的半数确认信息后,才会更新信息。
4、领导者节点返回给客户端更新信息结果,并广播通知所有的群众节点这次更改已经提交了。
日志条目包含序号和任期号,同一个任期内条目序号不会更改且位置固定,并且领导者节点同步日志时,会把紧接着之前条目的序号和任期号一起同步,群众节点找不到之前条目的序号和任期号就会拒绝接收新日志,这样就会保证日志同步的一致性(如若因网络问题出现了群众节点和Leader节点不一致,领导者节点会从后往前试,一次次的同步失败后的前一条日志条目,直到找到群众节点日志的一致位置点,然后从一致位置点往后逐条覆盖后边的日志)
总结
- 三种角色
- 选举流程
- 日志同步流程