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.95k stars 881 forks source link

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

Closed gamezhoulei closed 5 months ago

gamezhoulei commented 5 months ago

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

hnwyllmm commented 5 months ago

这个需求听起来不合理啊

gamezhoulei commented 5 months ago

这个需求听起来不合理啊

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

ehds commented 5 months ago

这个需求听起来不合理啊

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

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

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

gamezhoulei commented 5 months ago

这个需求听起来不合理啊

怎么说。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 5 months ago

这个需求听起来不合理啊

怎么说。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 强制超时发起选举: https://github.com/baidu/braft/blob/b37c610039aa34d6df2e5bda12f830003561b08b/src/braft/node.cpp#L1135-L1139

follower 处理选举请求: https://github.com/baidu/braft/blob/b37c610039aa34d6df2e5bda12f830003561b08b/src/braft/node.cpp#L2199-L2207 ps:braft 官方没有提供该接口(代替 leader transfer_leader), 这里只是提供一个思路。

gamezhoulei commented 5 months ago

这个需求听起来不合理啊

怎么说。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 强制超时发起选举:

https://github.com/baidu/braft/blob/b37c610039aa34d6df2e5bda12f830003561b08b/src/braft/node.cpp#L1135-L1139

follower 处理选举请求:

https://github.com/baidu/braft/blob/b37c610039aa34d6df2e5bda12f830003561b08b/src/braft/node.cpp#L2199-L2207

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

感谢大佬

ivanallen commented 4 months ago

这个需求听起来不合理啊

怎么说。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 强制超时发起选举:

https://github.com/baidu/braft/blob/b37c610039aa34d6df2e5bda12f830003561b08b/src/braft/node.cpp#L1135-L1139

follower 处理选举请求:

https://github.com/baidu/braft/blob/b37c610039aa34d6df2e5bda12f830003561b08b/src/braft/node.cpp#L2199-L2207

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

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

ehds commented 4 months ago

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

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

可以使用这种方式。

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