baidu / braft

An industrial-grade C++ implementation of RAFT consensus algorithm based on brpc, widely used inside Baidu to build highly-available distributed systems.
Apache License 2.0
3.86k stars 863 forks source link

有没有可能出现两次选举成功的间隔小于election_timeout导致lease read失效? #405

Open cangfengzhs opened 1 year ago

cangfengzhs commented 1 year ago

如下case:

三节点{A, B, C}

1. A向BC请求投票
2. BC都成功给A投票
3. B选举超时,开始preVote
4. A当选为Leader (Term=1),之后开始向BC发送心跳
5. B向AC请求投票
6. C成给B投票
7. B当选为Leader(Term=2)

follower在handleRequestVoteRequest中vote成功时,并没有renew follower_lease。这种情况下follower(B)在vote成功后会立即开始新的一轮选举,导致AB两个node在很短时间内先后当选为Leader

会有这种情况发生吗?

hnwyllmm commented 1 year ago

Prevote为什么不失败呢?

cangfengzhs commented 1 year ago

B向C请求preVote,C会返回成功啊

cangfengzhs commented 1 year ago

https://github.com/sofastack/sofa-jraft/blob/19ed179e02ee9108adc0bbf66badb47f62c62af8/jraft-core/src/main/java/com/alipay/sofa/jraft/core/NodeImpl.java#L1291

在JRaft的stepdown中有更新updateLastLeaderTimestamp,保证了之后的handleElectionTimeout在尝试选举前检查lastLeaderTimestamp间隔小于选举间隔。

在Braft中起到类似作用的应该是FollowerLease,但是在step_down函数中,并没有调用_follower_lease.renew()。

是有其他机制来避免我上面说的问题吗

ehds commented 1 year ago

https://github.com/sofastack/sofa-jraft/blob/19ed179e02ee9108adc0bbf66badb47f62c62af8/jraft-core/src/main/java/com/alipay/sofa/jraft/core/NodeImpl.java#L1291

在JRaft的stepdown中有更新updateLastLeaderTimestamp,保证了之后的handleElectionTimeout在尝试选举前检查lastLeaderTimestamp间隔小于选举间隔。

在Braft中起到类似作用的应该是FollowerLease,但是在step_down函数中,并没有调用_follower_lease.renew()。

是有其他机制来避免我上面说的问题吗

从目前实现来看,当raft_enable_leader_lease 开启时,的确可能发生上述现象。即节点刚投票成功后,等待 leader 的心跳前,如果此时 election_timer 超时, 或者已经超时,只不过在等待锁。那么该节点可以成功发起 PrevVote, 从而触发下一个 term 的选举, 而上一个 term 的 leader 却还在 lease有效期内。

但是在实际情况中,该问题不会导致严重的后果。因为当 leader 当选成功后,并不会立即调用 fsm->on_leader_start, 而是会先将当前最新的 configuration 复制到大多数节点(commit)后才会正式对外提供服务。 所以,即使发生上述情况,老term的 leader 会无法完成第一个日志的复制,并且发现已经有新的leader产生,从而转为follwer。

综上上述现象会发生,但是仅发生在老 term 的 leader 当选以及第一次日志复制过程中,而该过程并不会对外提供服务,所以是安全的。 对于该问题,论文 $5.2 节描述如下:

server remains in follower state as long as it receives valid RPCs from a leader or candidate.

image

所以从更严格的角度来说,是应该在投票后(收到了candidate的请求)进行重新计时。

cangfengzhs commented 1 year ago

万分感谢!