baidu/braft

在leader已经异常退出的时候, 如何快速选出新leader

gamezhoulei opened this issue · 8 comments

你好, 请问下, 如果某个leader已经异常退出了, 但是braft集群中, 还未达到election_timeout的时间, 此时leader仍然默认是正常状态, 有办法可以从剩余的follower中, 快速选出新的leader来提供服务么

这个需求听起来不合理啊

怎么说。election_timeout默认设置为5, 如果leader异常了, 5s内无法选出新的主,这5s都不能对外提供服务。所以希望有明确异常的时候,能够提前触发选主。当然,可以调整election_timeout更小, 但是这又可能引入频繁的选主,导致震荡。

ehds commented

这个需求听起来不合理啊

怎么说。election_timeout默认设置为5, 如果leader异常了, 5s内无法选出新的主,这5s都不能对外提供服务。所以希望有明确异常的时候,能够提前触发选主。当然,可以调整election_timeout更小, 但是这又可能引入频繁的选主,导致震荡。

如果你真的需要这个功能,可以试试 timeout_now_request 这个请求(也是现在 transfer_leader 的功能),手动强制触发 follower timeout。

但是这个前提是:你必须得保证目前 leader 的确已经退出了,否则存在双主的可能。

这个需求听起来不合理啊

怎么说。election_timeout默认设置为5, 如果leader异常了, 5s内无法选出新的主,这5s都不能对外提供服务。所以希望有明确异常的时候,能够提前触发选主。当然,可以调整election_timeout更小, 但是这又可能引入频繁的选主,导致震荡。

如果你真的需要这个功能,可以试试 timeout_now_request 这个请求(也是现在 transfer_leader 的功能),手动强制触发 follower timeout。

但是这个前提是:你必须得保证目前 leader 的确已经退出了,否则存在双主的可能。

这个会不会因为FLAGS_raft_enable_leader_lease, 即使触发了vote,也没办法。。强制切主
另外一个follower在prevote阶段,检查votable_time_from_now, 但是因为election_timeout还是5s

ehds commented

这个需求听起来不合理啊

怎么说。election_timeout默认设置为5, 如果leader异常了, 5s内无法选出新的主,这5s都不能对外提供服务。所以希望有明确异常的时候,能够提前触发选主。当然,可以调整election_timeout更小, 但是这又可能引入频繁的选主,导致震荡。

如果你真的需要这个功能,可以试试 timeout_now_request 这个请求(也是现在 transfer_leader 的功能),手动强制触发 follower timeout。
但是这个前提是:你必须得保证目前 leader 的确已经退出了,否则存在双主的可能。

这个会不会因为FLAGS_raft_enable_leader_lease, 即使触发了vote,也没办法。。强制切主 另外一个follower在prevote阶段,检查votable_time_from_now, 但是因为election_timeout还是5s

强制timeout,不会走 prev_vote, 直接走 elect,并且 request 带上 old_leader_stepped_down,另外的 follower 不会受 lease 的影响,具体看实现代码(实际上就是代替 leader 发起 transfer_leader ):

follower 强制超时发起选举:

braft/src/braft/node.cpp

Lines 1135 to 1139 in b37c610

response->set_success(true);
// Parallelize Response and election
run_closure_in_bthread(done_guard.release());
elect_self(&lck, request->old_leader_stepped_down());
// Don't touch any mutable field after this point, it's likely out of the

follower 处理选举请求:

braft/src/braft/node.cpp

Lines 2199 to 2207 in b37c610

if (_state == STATE_FOLLOWER &&
request->has_disrupted_leader() &&
_current_term == request->disrupted_leader().term() &&
0 == disrupted_leader_id.parse(request->disrupted_leader().peer_id()) &&
_leader_id == disrupted_leader_id) {
// The candidate has already disrupted the old leader, we
// can expire the lease safely.
_follower_lease.expire();
}

ps:braft 官方没有提供该接口(代替 leader transfer_leader), 这里只是提供一个思路。

这个需求听起来不合理啊

怎么说。election_timeout默认设置为5, 如果leader异常了, 5s内无法选出新的主,这5s都不能对外提供服务。所以希望有明确异常的时候,能够提前触发选主。当然,可以调整election_timeout更小, 但是这又可能引入频繁的选主,导致震荡。

如果你真的需要这个功能,可以试试 timeout_now_request 这个请求(也是现在 transfer_leader 的功能),手动强制触发 follower timeout。
但是这个前提是:你必须得保证目前 leader 的确已经退出了,否则存在双主的可能。

这个会不会因为FLAGS_raft_enable_leader_lease, 即使触发了vote,也没办法。。强制切主 另外一个follower在prevote阶段,检查votable_time_from_now, 但是因为election_timeout还是5s

强制timeout,不会走 prev_vote, 直接走 elect,并且 request 带上 old_leader_stepped_down,另外的 follower 不会受 lease 的影响,具体看实现代码(实际上就是代替 leader 发起 transfer_leader ):

follower 强制超时发起选举:

braft/src/braft/node.cpp

Lines 1135 to 1139 in b37c610

response->set_success(true);
// Parallelize Response and election
run_closure_in_bthread(done_guard.release());
elect_self(&lck, request->old_leader_stepped_down());
// Don't touch any mutable field after this point, it's likely out of the

follower 处理选举请求:

braft/src/braft/node.cpp

Lines 2199 to 2207 in b37c610

if (_state == STATE_FOLLOWER &&
request->has_disrupted_leader() &&
_current_term == request->disrupted_leader().term() &&
0 == disrupted_leader_id.parse(request->disrupted_leader().peer_id()) &&
_leader_id == disrupted_leader_id) {
// The candidate has already disrupted the old leader, we
// can expire the lease safely.
_follower_lease.expire();
}

ps:braft 官方没有提供该接口(代替 leader transfer_leader), 这里只是提供一个思路。

感谢大佬

这个需求听起来不合理啊

怎么说。election_timeout默认设置为5, 如果leader异常了, 5s内无法选出新的主,这5s都不能对外提供服务。所以希望有明确异常的时候,能够提前触发选主。当然,可以调整election_timeout更小, 但是这又可能引入频繁的选主,导致震荡。

如果你真的需要这个功能,可以试试 timeout_now_request 这个请求(也是现在 transfer_leader 的功能),手动强制触发 follower timeout。
但是这个前提是:你必须得保证目前 leader 的确已经退出了,否则存在双主的可能。

这个会不会因为FLAGS_raft_enable_leader_lease, 即使触发了vote,也没办法。。强制切主 另外一个follower在prevote阶段,检查votable_time_from_now, 但是因为election_timeout还是5s

强制timeout,不会走 prev_vote, 直接走 elect,并且 request 带上 old_leader_stepped_down,另外的 follower 不会受 lease 的影响,具体看实现代码(实际上就是代替 leader 发起 transfer_leader ):

follower 强制超时发起选举:

braft/src/braft/node.cpp

Lines 1135 to 1139 in b37c610

response->set_success(true);
// Parallelize Response and election
run_closure_in_bthread(done_guard.release());
elect_self(&lck, request->old_leader_stepped_down());
// Don't touch any mutable field after this point, it's likely out of the

follower 处理选举请求:

braft/src/braft/node.cpp

Lines 2199 to 2207 in b37c610

if (_state == STATE_FOLLOWER &&
request->has_disrupted_leader() &&
_current_term == request->disrupted_leader().term() &&
0 == disrupted_leader_id.parse(request->disrupted_leader().peer_id()) &&
_leader_id == disrupted_leader_id) {
// The candidate has already disrupted the old leader, we
// can expire the lease safely.
_follower_lease.expire();
}

ps:braft 官方没有提供该接口(代替 leader transfer_leader), 这里只是提供一个思路。

如果只是网络故障, leader 并未退出,这个方案应该还是会出现脑裂吧?

ehds commented

题主在这里的前提条件是:

leader 已经异常退出了 (node 的进程已经退出)。

可以使用这种方式。

至于你说的如果只是网络故障,不在这个前提条件内。