diff --git a/docs/changelog/83215.yaml b/docs/changelog/83215.yaml new file mode 100644 index 000000000000..3274a16861fa --- /dev/null +++ b/docs/changelog/83215.yaml @@ -0,0 +1,5 @@ +pr: 83215 +summary: Move Get Snapshots Serialization to Management Pool +area: Snapshot/Restore +type: bug +issues: [] diff --git a/server/src/main/java/org/elasticsearch/action/ActionModule.java b/server/src/main/java/org/elasticsearch/action/ActionModule.java index 7763854f9e77..3581b54cb7a9 100644 --- a/server/src/main/java/org/elasticsearch/action/ActionModule.java +++ b/server/src/main/java/org/elasticsearch/action/ActionModule.java @@ -704,7 +704,7 @@ public void initRestHandlers(Supplier nodesInCluster) { registerHandler.accept(new RestDeleteRepositoryAction()); registerHandler.accept(new RestVerifyRepositoryAction()); registerHandler.accept(new RestCleanupRepositoryAction()); - registerHandler.accept(new RestGetSnapshotsAction()); + registerHandler.accept(new RestGetSnapshotsAction(threadPool)); registerHandler.accept(new RestCreateSnapshotAction()); registerHandler.accept(new RestCloneSnapshotAction()); registerHandler.accept(new RestRestoreSnapshotAction()); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java index 56111e882f2f..dfd4f77156ac 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java @@ -86,7 +86,11 @@ public TransportGetSnapshotsAction( GetSnapshotsRequest::new, indexNameExpressionResolver, GetSnapshotsResponse::new, - ThreadPool.Names.SAME + ThreadPool.Names.MANAGEMENT // Execute this on the management pool because creating the response can become fairly expensive + // for large repositories in the verbose=false case when there are a lot of indices per snapshot. + // This is intentionally not using the snapshot_meta pool because that pool is sized rather large + // to accommodate concurrent IO and could consume excessive CPU resources through concurrent + // verbose=false requests that are CPU bound only. ); this.repositoriesService = repositoriesService; } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetSnapshotsAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetSnapshotsAction.java index e0713057340b..ebc63dc68aef 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetSnapshotsAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetSnapshotsAction.java @@ -13,9 +13,10 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.DispatchingRestToXContentListener; import org.elasticsearch.rest.action.RestCancellableNodeClient; -import org.elasticsearch.rest.action.RestToXContentListener; import org.elasticsearch.search.sort.SortOrder; +import org.elasticsearch.threadpool.ThreadPool; import java.io.IOException; import java.util.List; @@ -31,6 +32,12 @@ */ public class RestGetSnapshotsAction extends BaseRestHandler { + private final ThreadPool threadPool; + + public RestGetSnapshotsAction(ThreadPool threadPool) { + this.threadPool = threadPool; + } + @Override public List routes() { return List.of(new Route(GET, "/_snapshot/{repository}/{snapshot}")); @@ -76,6 +83,9 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC getSnapshotsRequest.masterNodeTimeout(request.paramAsTime("master_timeout", getSnapshotsRequest.masterNodeTimeout())); return channel -> new RestCancellableNodeClient(client, request.getHttpChannel()).admin() .cluster() - .getSnapshots(getSnapshotsRequest, new RestToXContentListener<>(channel)); + .getSnapshots( + getSnapshotsRequest, + new DispatchingRestToXContentListener<>(threadPool.executor(ThreadPool.Names.MANAGEMENT), channel, request) + ); } }