选举
再来看心跳监测请求:如果a是一个 secondary,那么a会定时检测是否需要选举自己成为 primary。其检测内容包括:
1.是否集群中有其它节点认为自己是 primary?
2.a节点自己是否已经是 primary?
3.a节点自己是否有资格成为 primary?
如果这三个问题中的任何一个回答是肯定的,那么a节点就不会试图把自己变成primary。(即:只有当a节点是一个能够当 primary 的secondary,并且其它节点都不是primary时,a才会发起选举并选自己为primary)
而当a发现现在需要一个 primary 并且自己又正好可以充当时,它就会发起一轮选举:a节点会向b、c节点各发起一个请求包,告知他们”我认为我可以接管 primary 的角色,你们觉得怎么样?“
当b和c收到上面的请求包时,他们会进行下面几项检测:
1.他们是否已经支持集群中有一个primary了?
2.他们自己的数据是否比a节点更新?
3.是否有其它节点的数据比a节点更新?
如果上面条件有任何一个满足,那么他们都会认为a不够资格成为 primary,他们会发送一个返回包告知a说”停止选举!“。而如果三个条件都不成立,也就是说他们认为目前集群中确实没有 primary,并且a的数据又是最新的,那么他们会发送返回包告知a说”没问题“。
如果a收到”停止选举!“的返回,那么他会马上停止选举并保持自己为 sencondary 状态。
如果a收到所有其它节点都返回说”没问题“,那么他会进入选举过程的第二阶段。
在第二阶段中,a会向其它节点发送一个包,说”我宣布我已经是 primary 了“。这时候,b和c节点再进行一些最终的确认:上面的判断过的所有条件是否依然表明a可以做 primary,如果确实如此,那么他们会在本轮 primary 选举中向a出赞成票。并且他们投完赞成票后,30秒内不会再做其它投票决定。
上面是说如果第二次确认还是通过的情况,那么如果最终确认没有通过呢。他们会投一个反对票,反对a成为 primary,如果有反对票产生,那么这一轮选举就失败了。a还是保持 secondary 的身份。
假设一种情况,如果b给a投了赞成票,而c给a投了反对票。那这时候b由于投了赞成票,它在30秒内不能再进行投票。所以如果这时候c发起选举想让自己成为 primary,那么c这时候必须要获得a的赞成票。因为这时候b不能投票,为了获取多数票,c必须获得a的赞成票。
所以投票的规则是这样的:如果没有人投反对票,并且赞成票的比例过半,那么本轮选举对象就能够成为 primary。