问题是如何产生的
初始是A,B,C三个节点,现在要扩展到5个节点。A,B,C三个节点已经完成了选举,A,B都选A,而C选自己,那么A是leader。现在要将视图变为ABCDE,变更同时A,B和C发生了网络分区,A,B看到的视图仍然是A,B,C三个节点,而CDE看到的视图是ABCDE五个节点,AB可以在旧视图之上选举leader,而CDE的也可以在新视图上选举leader,集群中同时出现了两个leader。
处理办法
把扩容到5个节点过程分成两步来做,每次扩容一个节点。先将视图变为ABCD,同时A,B和C发生了网络分区,AB看到的配置仍然是ABC三个节点,而CD看到的是ABCD是四个节点,而只有CD两个节点投票结果无法构成大多数,此时不会导致新的leader出现。而将4节点变更成5节点,需要等待4节点的拓扑全部被应用之后才可以继续进行。假设四节点的表决结果是A,B,C选择A而D选择自己(必须先有一个主),此时加入节点E,不管如何分区(A|BCDE,A看到的视图是ABCD,而BCDE看到视图是ABCDE,A的网络分区无法选举主,只有BCDE可以使用新视图选举leader),(AB|CDE,AB同样无法选举leader,CDE可以在新视图下选举leader),(ABC|DE,ABC可以在旧视图下选举leader,DE在新视图下无法选出leader),(ABCD|E, ABCD可以在旧视图下选举出leader,而E无法选举leader)都不会出现两个leader。
总结
raft增加节点时发生网络分区,可能两个网路分区看到的全局配置不同,各个分区根据自己看到的视图进行选举时,可能会选出多个leader。通过将视图变更的步骤分解为多步进行,每次只变化一个节点,这样要两个分区在各自的视图上有大多数的情况出现,那这两个区域也就必须是重叠的,有重叠区域也就要求这两个区域是没有隔离的,反面证明不会出现同时有两个大多数情况产生。