-
Notifications
You must be signed in to change notification settings - Fork 1k
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
node not part of the cluster is not allowed to vote #477
Conversation
316c59a
to
5778b92
Compare
5778b92
to
3907e87
Compare
@mkeeler I was thinking about this after our conversation today and I noticed few things:
Let me know what you think about this? |
So from our original discussions I was thinking the upgrade process would look like:
So with that sort of flow it wouldn't break compatibility. However I think I prefer your approach of adding the id to the I wonder whether we should add both the address and id of the peer server to the |
Thank you for taking a look at this @mkeeler About the upgrade process, I was thinking the same. I just called it a breaking change from the perspective that it need a special upgrade flow (2 restarts). About removing the |
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'm not all that familiar with this code but I had some high level questions/suggestion.
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 think you are already going back and adding some mixed protocol version tests which is great.
I suspect they will show some issues. I pointed out one place where I think there is a backwards compat concern but generally I think all the places where there is something like following probably needs to execute the code unconditionally instead of only if the proto isn't v4:
// encode some older proto 3 specific field
Basically we should always encode the older Leader
and Candidate
fields even if the proto is v4 so that if we are communicating with v3 nodes they can parse out the information appropiately.
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.
All the main code looks good. There are a handful of comment fixups and two logging fixes suggested but nothing that would require further review of.
Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>
Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>
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.
Nice! I think this is looking good.
If I understand correctly, this PR does the following:
- Increments to protocol version to 4, to indicate that we have new data available in the RPCHeader
- Uses that new
ID
in the header to check if the voter is actually in the configuration before considering the vote.
That makes sense to me, and in general having the ID and addr of the server sending the message seems like it is useful.
A few questions, a few more style suggestions. I think the only blockers are the API backwards compat, and the one place we don't version check req.Addr
.
But I do think if we can keep using req.Leader
and req.Candiate
when available, that might help keep the code easier to follow by reducing the number of places we check the protocol version.
I did not look at the tests much, hopefully Matt reviewed those more closely. Otherwise I can have a more detailed look.
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.
Thinking about the Protocol version increase, are you sure we need to increase the version?
Could we not optionally check if that field is set, and if it is do the new logic? If it's not then nothing we can do about it. That would avoid the difficult upgrade scenario, and allow everyone on V3 to get the benefit of this new check.
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.
Thank you for reviewing this @dnephin, see my comments in line.
I'm starting to think more that v4 is not necessary for this. Your point about using the new field and fallback to the old one when the new is empty seem reasonable to me and the fact that we always fill the old fields will ensure the compatibility with the nodes running a code version prior to this PR.
When I first did this with v4 version I was thinking that we will remove the Candidate and Leader field (or stop filling them in v4) but we ended up filling them all the time which ensure retro compatibility.
Testing the wire protocol compatibility is trivial and can easily be done the way you described.
What you think @mkeeler ?
… nil to fallback on the old fields.
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 definitely think this works better.
A couple comments about why we prefer the new field, and to document the existing fields accordingly.
I started to read over the tests a bit. I must admit some of the comments in the tests (which I think predate this PR) seem either misleading or confusing. I suspect I won't be able to review the test changes properly without spending a lot more time reading over Raft source first, but I trust Matt has done that review.
if len(req.RPCHeader.Addr) > 0 { | ||
ldr = string(req.RPCHeader.Addr) | ||
} else { | ||
ldr = string(req.Leader) | ||
} |
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.
Do we still need to do this? Any reason not to continue to use req.Leader
? Why do we prefer the new RPCHeader.Addr
?
If we are trying to phase it out, we should document that on the Leader
field.
Same question about the other two places we look at Leader
or Candidate
.
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 think we should aim to phaseout Leader and Candidate parameters, it make more sense to infer those values from the RPCHeader now and removing those will reduce the on the wire packet size sensibly. Also if we keep them it mean we need to document/test special cases behaviour (different values, Addr empty and Candidate not...).
I will add the deprecation comment for both Candidate and Leader
@dnephin I will leave this open for a day or so otherwise I will merge it. I would like to start working on bringing this changes to Consul, I have a couple of fixes blocked on this. |
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.
LGTM
When a follower is removed from the cluster it's removed from the configuration servers list but still run a follower loop (originally a follower node or
ShutdownOnRemove
set tofalse
for Leader). When that node timeout (because it's not receiving heartbeat from the other nodes in the cluster), it transition to a Candidate state and try to trigger an election. 2 possible cases:This uncover 2 issue:
Candidate state
. This is fixed in Forbid removed node from being aCandidate
#476RequestVoteRequest
only have theServerAddress
which do not represent a unique ID of the node, the one stored in the configuration server list. A test that reproduce the issue is in this PR.To keep track of things in this PR here is a list of what I intend to achieve:
ID
andAddr
field in RPCHeaderCandidate
andLeader
fields in Protocol Version 3 to usingAddr
(part of RPC header) field in protocol version 4ID
to validate that the node that is triggering an election is part of the latest configurationID
field as part of the API to be used in consulProtocolVersion
Test