-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-voters and automatic promotion #375
Conversation
This looks very promising. Initial thought is that we shouldn't need a new command for this and that this should be the behaviour of all |
Update after talking to @kjnilsson elsewhere. Removes voter promotion from the log, instead it is based on a single static target the nonvoter has to reach. Non-voters behave like regular followers, but are treated differently:
|
Thank you @illotum for working on this. Seems we will be able to add our stuff on top of it when time comes. :) One thing not clear for me, is why is there a need for automatic promotion? For a RabbitMQ use case, I would imagine the benefits to be not that big as the cluster does not change very often? |
@luos, at large enough scale nodes are lost regularly. I want to change the "quorum critical" report to acknowledge that the newly joined nodes are not ready, and restarting another member (out of three) will block quorum progress. After talking to Karl I am reverting the "minimalistic" version of the feature. It is still incomplete, but will be continued with the original design of tracking voter status in the log. |
Taking the WIP off. It is unlikely polished, but deserves a review. Some notes and concerns: Voter state is part of the Raft log, within the cluster membership record. It is also tracked at a higher level purely for convenience in handling RPCs. This is a fairly superficial improvement compared to the effort and risk of confusion. Totally willing to forgo it. Non-voting followers do not attempt to get elected, and ignore calls for election. All done within Their match_index is not included in commit computation, yet non-voters are listed in cluster members. This may be confusing to consumers, e.g. when newly added server doesn't block progress at first. Voter status is reported in Overall, most of the issues above would be addressed if I move this change into Updated transition diagram:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, some formatting and nitpicks only.
4fc73bd
to
484c209
Compare
1073dd4
to
556f009
Compare
250e700
to
3bede59
Compare
cae0448
to
33bdbe0
Compare
e6c474f
to
c681c6b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good. I have a few smaller suggestions.
I will start testing this PR with RabbitMQ
@illotum hi - I think there are both test and dialyzer failures but the checks pass as the tests aren't actually run atm. Would you mind rebasing from main which should pick up the relevant config to allow the PR ci suite to actually run. |
@illotum @kjnilsson and I seem to agree that using the "regular" (existing) Ra node identity for non-voting nodes should be fine. We can reuse it or even consider dropping the extra/new record field. |
…p with the log An opt-in ability of a cluster to ignore newly joined member until it catches up with the log: New = #{id => Id, ini_non_voter => ra:new_nvid()}, {ok, _, _} = ra:add_member(ServerRef, New), ok = ra:start_server(default, ClusterName, New, add_machine(), [ServerRef]), Voter status is stored in the cluster map of the server state and is part of every $ra_cluster_update. Additionally, nodes store their own status at the top level for ease of matching. Nodes also store their own satus in ra_state ETS table (breaking change), and present in overview. On every #append_entries_reply leader may choose to promote non-voter by issuing new `$ra_join` with desired voter status. Currently, only one promotion condition is implemented `{nonvoter, #{target := ra_index()}`. Non-voter will be promoted when it reaches the leaders log index at the time of joining.
Rebased and pushed the uid change. It is one of those small things that cascade widely, but a sum PR diff became saner IMO. Notably, local state and ETS now only hold It is briefly tested with ra-2.7.0 branch of rabbit. Will deal with dialyzer tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have done some testing in RabbitMQ with this Pr and so far it all looks good now.
Some questions and suggestions included which we need to address.
This is a draft.My take on #44, mostly a continuation of design discussed there. Some remaining (low-stakes) questions are left in italics, but they will not change much.
Notably, a departure from previous designs, the feature is completely opt-in. Both server start and member addition need be extended according to this example:
Voter status
Voter status is stored in the cluster map of the server state and is part of every
$ra_cluster_update
. Additionally, nodes store their own status at the top level for ease of matching.Nodes also store their own satus in
ra_state
ETS table (breaking change), and present in overview.Effect on Raft
Voters behave as before.
Non-voters ignore election timeouts and do not attempt to vote for others. Consensus calculation takes this into account, and non-voters have no effect on quorum size.
Transitions
ra:start_cluster
is unchanged, for new cluster of nonvoters will never elect a leader.ra:add_member
andra:start_server
now accept a map of server id and desired voter status. Legacy calls default to adding new server as a voter.On every
#append_entries_reply
leader may choose to promote non-voter by issuing new$ra_join
with desired voter status. Currently, only one promotion condition is implemented: non-voter will be promoted when it reaches the leaders log index at the time of joining.