Raft在网络分区时leader选举的一个疑问?

2019-10-08 15:34:13 浏览数 (1)

看到知乎有人提出这样一个问题

Raft在网络分区是leader选举的一个疑问?

假设有A,B,C,D,E五台机,A是leader,

某个时刻A,B出现了分区,但是A,C,D,E以及B,C,D,E都可以互相通信

B在超时没有收到心跳后,把term 1,发起leader选举,如果这段时间C,D,E没有写入更新的日志,由于B的term更大,就会被选为leader,A在后面的RPC中因为自己的term较小也会被降为follower。

问题是A成为follower之后又会按照上面B的方式发起选举成为leader,

同理B也会再次发起选举,这样周而复始会造成很大的网络开销吧,

请问我上面的分析有没有问题呢?

我的回答:

该问题做了一个假设,A B主机突然产生网络分区,并且之后没有客户端请求

由于B的term更大,就会被选为leader 这个理解错误的,但是这个情况可能出现,造成A B反复选举。直到有外界打破这样的循环。

但是这个情况可能出现,造成A B反复选举。直到有外界打破这样的循环。

为了解决这样问题,你想一想在有新领导情况下,

能随便一个说我是预备领导,都来选举我。,我什么条件都符合

有2个解决方式:

(1)

心跳时间和检测故障超时时间 不一样的,通过设置大小来消除这个问

题。大家都说没有问题,你说有问题,是没有人同意的。

(2)etcd解决方式 和上面道理一样。

PreVote

这是为避免发生无意义选举的一个机制,当learder没挂掉时,因为发生网络分区导致少数服务在一个分区内,他们因为连不上learder会不断的发起选举,任期号不断增加。导致网络分区恢复时他的 任期 号大于learder,从而发送选举,扰乱集群。

prevote 要求节点在开始选举前,必须先和所有其他节点进行一次通讯,如果超过了半数以上响应才能开始选举。 节点会先进入PreCandidate状态此时不会增加自己的 任期号,当他可以和集群半数以上的节点通信时,才能进入Candidate状态开始正式选举 这样网络分区情况下,少数节点的分区不会不断发起选举也不会增加自己的任期号

如何选举领导呢

raft 协议解决CAP中CP问题,

在网络分区raft协议也能解决

如何选举领导 需要添加约束

1. 第一个想到是必须的大多人同意,这是这个有缺点 论文已经提到过。

2. 因此产生第二个约束,当前任期内记录记录必须有一条提交到大多数

针对你的问题:有client 请求情况下

A和B产生分区,因为A leader记录 是不可能同步到B的,B重新发起选举情况下,

在约束1的情况下,是不可能选举成领导的。出现A/B反复的提高自己任期,依然无用情况。

针对你的第二个问题 网络开销,即使一个节点挂了,leader也是无限传递log math的。

网络分区不会长久存在,如果这样,人工发现异常。做恢复操作。

然后自动选举leader, 发现B的任期虽然高,但是没有记录同步,不会成为新的leader。


0 人点赞