-
Notifications
You must be signed in to change notification settings - Fork 25k
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
[Zen2] Add low-level bootstrap implementation #34345
[Zen2] Add low-level bootstrap implementation #34345
Conversation
Today we inject the initial configuration of the cluster (i.e. the set of voting nodes) at startup. In reality we must support injecting the initial configuration after startup too. This commit adds low-level support for doing so as safely as possible.
Pinging @elastic/es-distributed |
@elasticmachine test this please |
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've left some minor comments and questions. Looks very good already.
if (currentState.getLastAcceptedConfiguration().isEmpty() == false) { | ||
throw new CoordinationStateRejectedException("Cannot set initial configuration: configuration has already been set"); | ||
} | ||
assert currentState.term() == 0 : currentState; |
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.
Is this duplicating the checks in CoordinationState.setInitialState
?
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.
Yes, except that these checks happen earlier.
foundPeerIds.add(getLocalNode().getId()); | ||
peerFinder.getFoundPeers().forEach(peer -> foundPeerIds.add(peer.getId())); | ||
if (votingConfiguration.hasQuorum(foundPeerIds) == false) { | ||
throw new CoordinationStateRejectedException("Cannot set initial configuration: no quorum found yet"); |
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.
maybe expand the message a bit to not enough nodes discovered yet so that they would form a quorum in the initial configuration
+ add the foundPeers to the message (not only the ids, but the full nodes).
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.
Ok, I pushed 5c47f55.
throw new CoordinationStateRejectedException("Cannot set initial configuration: no quorum found yet"); | ||
} | ||
|
||
logger.debug("setting initial configuration to {}", votingConfiguration); |
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 can log this at info level. This is a rare event, and worth an entry in the logs.
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.
Ok, I pushed dbb2b1a
server/src/main/java/org/elasticsearch/cluster/coordination/Coordinator.java
Show resolved
Hide resolved
server/src/test/java/org/elasticsearch/cluster/coordination/CoordinatorTests.java
Outdated
Show resolved
Hide resolved
cluster.getAnyNode().applyInitialConfiguration(); | ||
cluster.stabilise(defaultMillis( | ||
// the first election should succeed | ||
ELECTION_INITIAL_TIMEOUT_SETTING) // TODO this wait is unnecessary, we could trigger the election immediately |
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.
why does the first election succeed?
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.
In this case only one node has a nonempty configuration, so it's the only one that can pass through prevoting and win the election, so there's no election collisions. I expanded the comment in dcbacd8.
assertThat("setting initial configuration may fail with blackholed nodes", blackholedNodes, empty()); | ||
runFor(defaultMillis(DISCOVERY_FIND_PEERS_INTERVAL_SETTING) * 2, "discovery prior to setting initial configuration"); | ||
final ClusterNode bootstrapNode = getAnyNode(); | ||
bootstrapNode.applyInitialConfiguration(); |
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.
a bootstrap API will use networking an have this thing arrive in different times on the node. Should we already simulate a short network delay here? (i.e. schedule as a task)
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 would prefer not to, so we can use this to assert a tighter bound on the speed of bootstrapping. In most runs this doesn't happen (bootstrapping has already occurred at a random time in runRandomly()
).
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.
Thanks, I addressed your comments.
if (currentState.getLastAcceptedConfiguration().isEmpty() == false) { | ||
throw new CoordinationStateRejectedException("Cannot set initial configuration: configuration has already been set"); | ||
} | ||
assert currentState.term() == 0 : currentState; |
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.
Yes, except that these checks happen earlier.
assertThat("setting initial configuration may fail with blackholed nodes", blackholedNodes, empty()); | ||
runFor(defaultMillis(DISCOVERY_FIND_PEERS_INTERVAL_SETTING) * 2, "discovery prior to setting initial configuration"); | ||
final ClusterNode bootstrapNode = getAnyNode(); | ||
bootstrapNode.applyInitialConfiguration(); |
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 would prefer not to, so we can use this to assert a tighter bound on the speed of bootstrapping. In most runs this doesn't happen (bootstrapping has already occurred at a random time in runRandomly()
).
cluster.getAnyNode().applyInitialConfiguration(); | ||
cluster.stabilise(defaultMillis( | ||
// the first election should succeed | ||
ELECTION_INITIAL_TIMEOUT_SETTING) // TODO this wait is unnecessary, we could trigger the election immediately |
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.
In this case only one node has a nonempty configuration, so it's the only one that can pass through prevoting and win the election, so there's no election collisions. I expanded the comment in dcbacd8.
server/src/test/java/org/elasticsearch/cluster/coordination/CoordinatorTests.java
Outdated
Show resolved
Hide resolved
foundPeerIds.add(getLocalNode().getId()); | ||
peerFinder.getFoundPeers().forEach(peer -> foundPeerIds.add(peer.getId())); | ||
if (votingConfiguration.hasQuorum(foundPeerIds) == false) { | ||
throw new CoordinationStateRejectedException("Cannot set initial configuration: no quorum found yet"); |
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.
Ok, I pushed 5c47f55.
throw new CoordinationStateRejectedException("Cannot set initial configuration: no quorum found yet"); | ||
} | ||
|
||
logger.debug("setting initial configuration to {}", votingConfiguration); |
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.
Ok, I pushed dbb2b1a
server/src/main/java/org/elasticsearch/cluster/coordination/Coordinator.java
Show resolved
Hide resolved
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
server/src/main/java/org/elasticsearch/cluster/coordination/Coordinator.java
Show resolved
Hide resolved
Build failed due to maven flakiness? @elasticmachine test this please. |
Today we inject the initial configuration of the cluster (i.e. the set of
voting nodes) at startup. In reality we must support injecting the initial
configuration after startup too. This commit adds low-level support for doing
so as safely as possible.