Skip to content
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

Optimize TransportNodesAction to selectively avoid sending list of Di… #14531

Conversation

Pranshu-S
Copy link
Contributor

@Pranshu-S Pranshu-S commented Jun 25, 2024

Description

In the current implementation, every transport action extending TransportNodesAction includes all discovery nodes in the transport request sent to each node in the cluster. This approach leads to performance bottlenecks in large clusters due to redundant data transmission. Specifically:

  1. Increased Network Traffic: The same list of discovery nodes is written n^2 times (where n is the number of nodes), causing unnecessary network traffic and increased IO.
  2. Write/Read Latency: The excessive data transmission contributes to higher overall latency for both write and read operations.
  3. Netty Buffer Bottleneck: When using plugins like Netty for inter-node communication, the buffer becomes overloaded with redundant discovery node information, increasing the size of the request and correspondingly reducing the amount of requests which can fit in the Netty buffer.

image

This PR proposes a solution to address these bottlenecks by selectively skipping the resolution of concrete nodes at the transport layer. This optimization will significantly reduce redundant data transmission and improve overall performance in large clusters.

To do this, flag was introduced on the BaseNodeRequest ClasspopulateDiscoveryNodesInTransportRequest. Requests in this flag overriden to False will skip adding the concrete nodes data into the request. Currently it is only implemented in NodeStats, ClusterStats and NodeInfo Call from the rest layer.

The perf gains are significant (tested in a large 1k node domain)

API Stats Default (s) Optimized (s) % Reduction
_nodes/stats Average 10.03409 1.41749 -86%
P90 12.54658 5.80648 -54%
Max 16.39159 11.61396 -30%
Min 6.41173 0.35198 -95%
_nodes Average 8.61528 3.66873 -58%
P90 13.19499 8.30744 -38%
Max 19.39874 15.91021 -18%
Min 6.56645 1.17164 -83%
_cat/nodes Average 21.45014 1.0651 -96%
P90 26.95066 1.79513 -94%
Max 36.11789 17.46319 -52%
Min 15.26925 0.20656 -99%
_cluster/stats Average 9.82926 2.01671 -80%
P90 12.31955 6.52061 -48%
Max 17.9214 12.50545 -31%
Min 6.22867 0.27218 -96%

Related Issues

Resolves #[Issue number to be closed when this PR is merged]

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Copy link
Contributor

❌ Gradle check result for 9e66ed2: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

}

void start() {
final DiscoveryNode[] nodes = request.concreteNodes();
logger.info(request.getClass().getSimpleName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would lead to heavy logging. Please remove this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure Vikas, I intended to work on the logs for testing. Will remove them prior to raising the PR.

@@ -234,14 +266,28 @@ class AsyncAction {
this.request = request;
this.listener = listener;
if (request.concreteNodes() == null) {
resolveRequest(request, clusterService.state());
assert request.concreteNodes() != null;
if (optimizedTransportActionNames.contains(request.getClass().getSimpleName())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some tests for this? Also, have you executed all existing tests and made sure that they are passing after your change. If yes, then please confirm this in the PR description.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that node left and node added scenarios are covered properly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have modified the draft PR approach. Will make sure I add all the necessary tests covering different scenarios.

@Pranshu-S Pranshu-S force-pushed the TransportNodesActionOptimisation-DiscoveryNodeFix branch from 9e66ed2 to 4f6b6ed Compare July 11, 2024 14:27
Copy link
Contributor

❌ Gradle check result for 4f6b6ed: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

…s, NodesInfo and ClusterStats call

Signed-off-by: Pranshu Shukla <[email protected]>
@Pranshu-S Pranshu-S force-pushed the TransportNodesActionOptimisation-DiscoveryNodeFix branch from 4f6b6ed to d2ef37d Compare July 12, 2024 13:18
Copy link
Contributor

❌ Gradle check result for d2ef37d: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: Pranshu Shukla <[email protected]>
Copy link
Contributor

❌ Gradle check result for 469cd6a: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: Pranshu Shukla <[email protected]>
Copy link
Contributor

❌ Gradle check result for 03c35df: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: Pranshu Shukla <[email protected]>
Copy link
Contributor

❌ Gradle check result for b7b8754: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: Pranshu Shukla <[email protected]>
Copy link
Contributor

❌ Gradle check result for 31f030c: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@Pranshu-S
Copy link
Contributor Author

Closing this PR in virtue of clone PR - #14749

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants