6.2 重置节点列表
Last updated
Last updated
当集群中大多数节点不可用时,不能通过 add_peer
/remove_peer
/change_peer
等接口进行配置变更,则可以使用 reset_peer
重置节点配置:
用户调用 reset_peers
重置某个节点的配置
若当前节点有配置变更正在进行,则返回 EBUSY
将当前节点的内存配置设为新配置,并调用 step_down
准备重新选举;在此之后,重置接口返回成功,但变更仍在继续。
超过 election_timeout_ms
时间后,集群进行重新选举,并且当前节点一定会被当选为 Leader,原因如下:
选举是以节点配置为选举视角,而老集群中只有被重置了的节点才拥有新集群配置
新加入的节点没有任何日志
待其当选 Leader 后,会将新配置日志进行持久化,并复制给所有新集群中的成员:
5.1 若配置日志持久化成功,则重置成功
5.2 若在此之前 Leader Crash 了,则重置失败,用户需要重新调用 reset_peers
其他节点在接收到新配置后,则立即应用新配置
从上可以看出,reset_peer
是通过先将一个节点内存中的配置设为新配置,使其以新配置的视角进行重新选举,这样可以确保该节点能成为 Leader。待其成为 Leader 后,将新配置持久化,并且通过日志分发新配置,使新集群中的所有节点都使用新配置。
不建议使用 reset_peers
,因为其会破坏数据的一致性,而且可能会造成脑裂,下图这个列子将会说明这个问题:
T1:由 ABCDE
5 个节点组成的集群中,CDE
宕机导致集群没有 Leader
T2:将 A
节点通过 reset_peer
重置为 AB
,其成功选举成 Leader,并将配置同步给 B
T3:节点 CDE
重新上线
T4:由于不再收到 Leader A
的心跳,CDE
重新选举并选出 Leader C
,此时集群中将同时存在 2 个 Leader
此时 Leader A
和 C
的 term
是一样的,其中的 B
节点会接收到这 2 个 Leader 的日志复制请求,而当前接受日志只检测日志的 term
和 index
,这可能会导致数据错乱,也就是说 B
中的连续日志可能一部分来自 A
,一部分来自 C
。
用户调用 reset_peers
重置节点配置,其流程详见以下注释:
该阶段就是集群进行选举,选举是以当前节点配置作为视角进行选举,所以只有执行重置的节点的配置是新集群配置,能选举成功。选举流程详见<3.1 选举流程>。
在节点成为 Leader 后,就会持久化新配置日志,并且通过复制将新配置日志同步给所有节点。所有节点接收到新配置日志后,就会立马应用该配置。具体的流程我们在<3.1 选举流程>中都已经介绍过了,详见: