-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
Faster GET _cluster/settings API #86405
Changes from 6 commits
75d179c
8a88827
25f0240
022864b
5666ecf
68394fd
7d91858
5fce1b3
49f2703
2abab4e
0499aab
8ff26f3
bdca67c
8a13ecd
fad4113
6c5f6fb
8aac2df
7019207
c870408
be83573
4d32a3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
pr: 86405 | ||
summary: Faster GET _cluster/settings API | ||
area: Infra/Core | ||
type: enhancement | ||
issues: | ||
- 82342 |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,116 @@ | ||||
/* | ||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||||
* or more contributor license agreements. Licensed under the Elastic License | ||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||||
* Side Public License, v 1. | ||||
*/ | ||||
|
||||
package org.elasticsearch.action.admin.cluster.settings; | ||||
|
||||
import org.elasticsearch.action.ActionRequestValidationException; | ||||
import org.elasticsearch.action.ActionResponse; | ||||
import org.elasticsearch.action.ActionType; | ||||
import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder; | ||||
import org.elasticsearch.action.support.master.MasterNodeReadRequest; | ||||
import org.elasticsearch.client.internal.ElasticsearchClient; | ||||
import org.elasticsearch.common.io.stream.StreamInput; | ||||
import org.elasticsearch.common.io.stream.StreamOutput; | ||||
import org.elasticsearch.common.settings.Settings; | ||||
import org.elasticsearch.xcontent.ToXContentObject; | ||||
import org.elasticsearch.xcontent.XContentBuilder; | ||||
|
||||
import java.io.IOException; | ||||
import java.util.Objects; | ||||
|
||||
import static org.elasticsearch.action.admin.cluster.settings.RestClusterGetSettingsResponse.PERSISTENT_FIELD; | ||||
import static org.elasticsearch.action.admin.cluster.settings.RestClusterGetSettingsResponse.TRANSIENT_FIELD; | ||||
|
||||
public class ClusterGetSettingsAction extends ActionType<ClusterGetSettingsAction.Response> { | ||||
|
||||
public static final ClusterGetSettingsAction INSTANCE = new ClusterGetSettingsAction(); | ||||
public static final String NAME = "cluster:admin/settings/get"; | ||||
|
||||
public ClusterGetSettingsAction() { | ||||
super(NAME, Response::new); | ||||
} | ||||
|
||||
/** | ||||
* Request to retrieve the cluster settings | ||||
*/ | ||||
public static class Request extends MasterNodeReadRequest<Request> { | ||||
public Request() {} | ||||
|
||||
public Request(StreamInput in) throws IOException { | ||||
super(in); | ||||
} | ||||
DaveCTurner marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
|
||||
@Override | ||||
public ActionRequestValidationException validate() { | ||||
return null; | ||||
} | ||||
} | ||||
|
||||
/** | ||||
* Cluster get settings request builder | ||||
*/ | ||||
public static class RequestBuilder extends MasterNodeReadOperationRequestBuilder<Request, Response, RequestBuilder> { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder, do we really need all this client-facing machinery? AFAIK this pattern was good for the transport client, but we have no transport client any more so I think we can just call the action directly in the one place it's currently used. |
||||
|
||||
public RequestBuilder(ElasticsearchClient client, ClusterGetSettingsAction action) { | ||||
super(client, action, new Request()); | ||||
} | ||||
} | ||||
|
||||
/** | ||||
* Response for cluster settings | ||||
*/ | ||||
public static class Response extends ActionResponse implements ToXContentObject { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be |
||||
private final Settings persistentSettings; | ||||
private final Settings transientSettings; | ||||
|
||||
public Response(StreamInput in) throws IOException { | ||||
super(in); | ||||
persistentSettings = Settings.readSettingsFromStream(in); | ||||
transientSettings = Settings.readSettingsFromStream(in); | ||||
} | ||||
|
||||
public Response(Settings persistentSettings, Settings transientSettings) { | ||||
this.persistentSettings = Objects.requireNonNullElse(persistentSettings, Settings.EMPTY); | ||||
this.transientSettings = Objects.requireNonNullElse(transientSettings, Settings.EMPTY); | ||||
} | ||||
|
||||
@Override | ||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||||
builder.startObject(); | ||||
|
||||
builder.startObject(PERSISTENT_FIELD); | ||||
persistentSettings.toXContent(builder, params); | ||||
builder.endObject(); | ||||
|
||||
builder.startObject(TRANSIENT_FIELD); | ||||
transientSettings.toXContent(builder, params); | ||||
builder.endObject(); | ||||
|
||||
builder.endObject(); | ||||
return builder; | ||||
} | ||||
|
||||
@Override | ||||
public void writeTo(StreamOutput out) throws IOException { | ||||
Settings.writeSettingsToStream(persistentSettings, out); | ||||
Settings.writeSettingsToStream(transientSettings, out); | ||||
} | ||||
|
||||
public Settings persistentSettings() { | ||||
return persistentSettings; | ||||
} | ||||
|
||||
public Settings transientSettings() { | ||||
return transientSettings; | ||||
} | ||||
|
||||
public Settings settings() { | ||||
return Settings.builder().put(persistentSettings).put(transientSettings).build(); | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this is the right way to get the combined settings, it didn't make sense to double serialize across the transport protocol. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks right: elasticsearch/server/src/main/java/org/elasticsearch/cluster/metadata/Metadata.java Line 1875 in 5791567
However I think it would be fine (preferable even) to send the combined settings separately from the transient and persistent ones, rather than duplicating this logic and risking getting it wrong. |
||||
} | ||||
} | ||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.action.admin.cluster.settings; | ||
|
||
import org.elasticsearch.action.ActionListener; | ||
import org.elasticsearch.action.support.ActionFilters; | ||
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; | ||
import org.elasticsearch.cluster.ClusterState; | ||
import org.elasticsearch.cluster.block.ClusterBlockException; | ||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; | ||
import org.elasticsearch.cluster.metadata.Metadata; | ||
import org.elasticsearch.cluster.service.ClusterService; | ||
import org.elasticsearch.common.inject.Inject; | ||
import org.elasticsearch.tasks.Task; | ||
import org.elasticsearch.threadpool.ThreadPool; | ||
import org.elasticsearch.transport.TransportService; | ||
|
||
public class TransportClusterGetSettingsAction extends TransportMasterNodeReadAction< | ||
ClusterGetSettingsAction.Request, | ||
ClusterGetSettingsAction.Response> { | ||
|
||
@Inject | ||
public TransportClusterGetSettingsAction( | ||
TransportService transportService, | ||
ClusterService clusterService, | ||
ThreadPool threadPool, | ||
ActionFilters actionFilters, | ||
IndexNameExpressionResolver indexNameExpressionResolver | ||
) { | ||
super( | ||
ClusterGetSettingsAction.NAME, | ||
transportService, | ||
clusterService, | ||
threadPool, | ||
actionFilters, | ||
ClusterGetSettingsAction.Request::new, | ||
indexNameExpressionResolver, | ||
ClusterGetSettingsAction.Response::new, | ||
ThreadPool.Names.SAME | ||
); | ||
grcevski marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@Override | ||
protected void masterOperation( | ||
Task task, | ||
ClusterGetSettingsAction.Request request, | ||
ClusterState state, | ||
ActionListener<ClusterGetSettingsAction.Response> listener | ||
) throws Exception { | ||
Metadata metadata = state.metadata(); | ||
listener.onResponse(new ClusterGetSettingsAction.Response(metadata.persistentSettings(), metadata.transientSettings())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should apply the node's |
||
} | ||
|
||
@Override | ||
protected ClusterBlockException checkBlock(ClusterGetSettingsAction.Request request, ClusterState state) { | ||
return null; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,7 @@ | |
import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; | ||
import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequestBuilder; | ||
import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse; | ||
import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsAction; | ||
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; | ||
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequestBuilder; | ||
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse; | ||
|
@@ -756,4 +757,26 @@ public interface ClusterAdminClient extends ElasticsearchClient { | |
* Delete specified dangling indices. | ||
*/ | ||
ActionFuture<AcknowledgedResponse> deleteDanglingIndex(DeleteDanglingIndexRequest request); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: this file only contains whitespace changes now |
||
/** | ||
* The cluster settings. | ||
* | ||
* @param request The cluster settings request | ||
* @return The result future | ||
*/ | ||
ActionFuture<ClusterGetSettingsAction.Response> clusterSettings(ClusterGetSettingsAction.Request request); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly here, I think this stuff is all unused in practice and best dropped. |
||
|
||
/** | ||
* The health of the cluster. | ||
* | ||
* @param request The cluster state request | ||
* @param listener A listener to be notified with a result | ||
*/ | ||
void clusterSettings(ClusterGetSettingsAction.Request request, ActionListener<ClusterGetSettingsAction.Response> listener); | ||
|
||
/** | ||
* The health of the cluster. | ||
*/ | ||
ClusterGetSettingsAction.RequestBuilder prepareClusterSettings(); | ||
|
||
} |
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 this needs to be under
cluster:monitor/*
(maybecluster:monitor/settings
?) so that it's still permitted by clients that only have the monitor privilege.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.
Good idea, this way I can undo some of the changes I needed to do in xpack.