-
Notifications
You must be signed in to change notification settings - Fork 25.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
Only connect to new nodes on new cluster state #39629
Only connect to new nodes on new cluster state #39629
Conversation
Today, when applying new cluster state we attempt to connect to all of its nodes as a blocking part of the application process. This is the right thing to do with new nodes, and is a no-op on any already-connected nodes, but is questionable on known nodes from which we are currently disconnected: there is a risk that we are partitioned from these nodes so that any attempt to connect to them will hang until it times out. This can dramatically slow down the application of new cluster states which hinders the recovery of the cluster during certain kinds of partition. If nodes are disconnected from the master then it is likely that they are to be removed as part of a subsequent cluster state update, so there's no need to try and reconnect to them like this. Moreover there is no need to attempt to reconnect to disconnected nodes as part of the cluster state application process, because we periodically try and reconnect to any disconnected nodes, and handle their disconnectedness reasonably gracefully in the meantime. This commit alters this behaviour to avoid reconnecting to known nodes during cluster state application. Resolves elastic#29025. Supersedes elastic#31547.
Pinging @elastic/es-distributed |
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.
initial pass
server/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
Outdated
Show resolved
Hide resolved
"connection cancelled by disconnection"); | ||
} | ||
|
||
Runnable ensureConnected(ActionListener<Void> listener) { |
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 it possible that ensureConnected and connect/disconnect are called in different threads at the same time? I'm not sure how we're protecting listeners from races
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, they can be called in different threads, but we only ever read or write listeners
under the mutex
. The listeners are never called under the mutex
so it is possible that the notifications happen out of order, but this is benign.
@andrershov you'll be pleased to hear I adjusted this to use a future 😁 |
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 @DaveCTurner , I have left some comments, otherwise looking good.
server/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
Show resolved
Hide resolved
server/src/test/java/org/elasticsearch/cluster/NodeConnectionsServiceTests.java
Show resolved
Hide resolved
server/src/test/java/org/elasticsearch/cluster/NodeConnectionsServiceTests.java
Show resolved
Hide resolved
server/src/test/java/org/elasticsearch/cluster/NodeConnectionsServiceTests.java
Show resolved
Hide resolved
server/src/test/java/org/elasticsearch/cluster/NodeConnectionsServiceTests.java
Outdated
Show resolved
Hide resolved
server/src/test/java/org/elasticsearch/cluster/NodeConnectionsServiceTests.java
Outdated
Show resolved
Hide resolved
server/src/test/java/org/elasticsearch/cluster/NodeConnectionsServiceTests.java
Outdated
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.
I added a few nits/minor comments.
server/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
Show resolved
Hide resolved
server/src/test/java/org/elasticsearch/cluster/NodeConnectionsServiceTests.java
Outdated
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.
Unfortunately, replacing the list of listeners with the future does not make the code much simpler. But I must confess I also cannot come up with an easier ConnectionTarget implementation, using future chaining.
Nice job! LGTM
server/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
Show resolved
Hide resolved
Today, when applying new cluster state we attempt to connect to all of its nodes as a blocking part of the application process. This is the right thing to do with new nodes, and is a no-op on any already-connected nodes, but is questionable on known nodes from which we are currently disconnected: there is a risk that we are partitioned from these nodes so that any attempt to connect to them will hang until it times out. This can dramatically slow down the application of new cluster states which hinders the recovery of the cluster during certain kinds of partition. If nodes are disconnected from the master then it is likely that they are to be removed as part of a subsequent cluster state update, so there's no need to try and reconnect to them like this. Moreover there is no need to attempt to reconnect to disconnected nodes as part of the cluster state application process, because we periodically try and reconnect to any disconnected nodes, and handle their disconnectedness reasonably gracefully in the meantime. This commit alters this behaviour to avoid reconnecting to known nodes during cluster state application. Resolves #29025.
Today, when applying new cluster state we attempt to connect to all of its
nodes as a blocking part of the application process. This is the right thing to
do with new nodes, and is a no-op on any already-connected nodes, but is
questionable on known nodes from which we are currently disconnected: there is
a risk that we are partitioned from these nodes so that any attempt to connect
to them will hang until it times out. This can dramatically slow down the
application of new cluster states which hinders the recovery of the cluster
during certain kinds of partition.
If nodes are disconnected from the master then it is likely that they are to be
removed as part of a subsequent cluster state update, so there's no need to try
and reconnect to them like this. Moreover there is no need to attempt to
reconnect to disconnected nodes as part of the cluster state application
process, because we periodically try and reconnect to any disconnected nodes,
and handle their disconnectedness reasonably gracefully in the meantime.
This commit alters this behaviour to avoid reconnecting to known nodes during
cluster state application.
Resolves #29025.
Supersedes #31547.