Skip to content

Commit c052282

Browse files
author
Hendrik Muhs
authored
[ML] Add backend for getting ML autoscaling resources (#97362)
add transport action to retrieve autoscaling metrics for ML autoscaling
1 parent 8151092 commit c052282

File tree

10 files changed

+605
-0
lines changed

10 files changed

+605
-0
lines changed

x-pack/plugin/core/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
exports org.elasticsearch.xpack.core.logstash;
7272
exports org.elasticsearch.xpack.core.ml.action;
7373
exports org.elasticsearch.xpack.core.ml.annotations;
74+
exports org.elasticsearch.xpack.core.ml.autoscaling;
7475
exports org.elasticsearch.xpack.core.ml.calendars;
7576
exports org.elasticsearch.xpack.core.ml.datafeed.extractor;
7677
exports org.elasticsearch.xpack.core.ml.datafeed;
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.core.ml.action;
9+
10+
import org.elasticsearch.action.ActionRequestValidationException;
11+
import org.elasticsearch.action.ActionResponse;
12+
import org.elasticsearch.action.ActionType;
13+
import org.elasticsearch.action.support.master.AcknowledgedRequest;
14+
import org.elasticsearch.common.io.stream.StreamInput;
15+
import org.elasticsearch.common.io.stream.StreamOutput;
16+
import org.elasticsearch.core.TimeValue;
17+
import org.elasticsearch.tasks.CancellableTask;
18+
import org.elasticsearch.tasks.Task;
19+
import org.elasticsearch.tasks.TaskId;
20+
import org.elasticsearch.xpack.core.ml.action.GetMlAutoscalingStats.Response;
21+
import org.elasticsearch.xpack.core.ml.autoscaling.MlAutoscalingStats;
22+
23+
import java.io.IOException;
24+
import java.util.Map;
25+
import java.util.Objects;
26+
27+
/**
28+
* Internal (no-REST) action to retrieve metrics for serverless autoscaling.
29+
*/
30+
public class GetMlAutoscalingStats extends ActionType<Response> {
31+
32+
public static final GetMlAutoscalingStats INSTANCE = new GetMlAutoscalingStats();
33+
public static final String NAME = "cluster:monitor/xpack/ml/autoscaling/stats/get";
34+
35+
public GetMlAutoscalingStats() {
36+
super(NAME, Response::new);
37+
}
38+
39+
public static class Request extends AcknowledgedRequest<Request> {
40+
41+
public Request(TimeValue timeout) {
42+
super(timeout);
43+
}
44+
45+
public Request(StreamInput in) throws IOException {
46+
super(in);
47+
}
48+
49+
@Override
50+
public ActionRequestValidationException validate() {
51+
return null;
52+
}
53+
54+
@Override
55+
public Task createTask(long id, String type, String action, TaskId parentTaskId, Map<String, String> headers) {
56+
return new CancellableTask(id, type, action, "get_ml_autoscaling_resources", parentTaskId, headers);
57+
}
58+
59+
@Override
60+
public int hashCode() {
61+
return Objects.hash(timeout);
62+
}
63+
64+
@Override
65+
public boolean equals(Object obj) {
66+
if (obj == null) {
67+
return false;
68+
}
69+
if (getClass() != obj.getClass()) {
70+
return false;
71+
}
72+
GetMlAutoscalingStats.Request other = (GetMlAutoscalingStats.Request) obj;
73+
return Objects.equals(timeout, other.timeout);
74+
}
75+
}
76+
77+
public static class Response extends ActionResponse {
78+
79+
private final MlAutoscalingStats autoscalingResources;
80+
81+
public Response(final MlAutoscalingStats autoscalingResources) {
82+
this.autoscalingResources = autoscalingResources;
83+
}
84+
85+
public Response(final StreamInput in) throws IOException {
86+
super(in);
87+
this.autoscalingResources = new MlAutoscalingStats(in);
88+
}
89+
90+
public MlAutoscalingStats getAutoscalingResources() {
91+
return autoscalingResources;
92+
}
93+
94+
@Override
95+
public void writeTo(StreamOutput out) throws IOException {
96+
autoscalingResources.writeTo(out);
97+
}
98+
99+
@Override
100+
public int hashCode() {
101+
return Objects.hash(autoscalingResources);
102+
}
103+
104+
@Override
105+
public boolean equals(Object obj) {
106+
if (obj == null) {
107+
return false;
108+
}
109+
if (getClass() != obj.getClass()) {
110+
return false;
111+
}
112+
GetMlAutoscalingStats.Response other = (GetMlAutoscalingStats.Response) obj;
113+
return Objects.equals(autoscalingResources, other.autoscalingResources);
114+
}
115+
}
116+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.core.ml.autoscaling;
9+
10+
import org.elasticsearch.common.io.stream.StreamInput;
11+
import org.elasticsearch.common.io.stream.StreamOutput;
12+
import org.elasticsearch.common.io.stream.Writeable;
13+
14+
import java.io.IOException;
15+
16+
public record MlAutoscalingStats(
17+
int nodes,
18+
long memoryInBytesSum,
19+
long modelMemoryInBytesSum,
20+
int minNodes,
21+
long extraSingleNodeModelMemoryInBytes,
22+
int extraSingleNodeProcessors,
23+
long extraModelMemoryInBytes,
24+
int extraProcessors,
25+
long removeNodeMemoryInBytes,
26+
long perNodeMemoryOverheadInBytes
27+
) implements Writeable {
28+
29+
public MlAutoscalingStats(StreamInput in) throws IOException {
30+
this(
31+
in.readVInt(), // nodes
32+
in.readVLong(), // memoryInBytesSum
33+
in.readVLong(), // modelMemoryInBytes
34+
in.readVInt(), // minNodes
35+
in.readVLong(), // extraSingleNodeModelMemoryInBytes
36+
in.readVInt(), // extraSingleNodeProcessors
37+
in.readVLong(), // extraModelMemoryInBytes
38+
in.readVInt(), // extraProcessors
39+
in.readVLong(), // removeNodeMemoryInBytes
40+
in.readVLong() // perNodeMemoryOverheadInBytes
41+
);
42+
}
43+
44+
@Override
45+
public void writeTo(StreamOutput out) throws IOException {
46+
out.writeVInt(nodes);
47+
out.writeVLong(memoryInBytesSum);
48+
out.writeVLong(modelMemoryInBytesSum);
49+
out.writeVInt(minNodes);
50+
out.writeVLong(extraSingleNodeModelMemoryInBytes);
51+
out.writeVInt(extraSingleNodeProcessors);
52+
out.writeVLong(extraModelMemoryInBytes);
53+
out.writeVInt(extraProcessors);
54+
out.writeVLong(removeNodeMemoryInBytes);
55+
out.writeVLong(perNodeMemoryOverheadInBytes);
56+
}
57+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.core.ml.action;
9+
10+
import org.elasticsearch.common.io.stream.Writeable;
11+
import org.elasticsearch.core.TimeValue;
12+
import org.elasticsearch.test.AbstractWireSerializingTestCase;
13+
import org.elasticsearch.xpack.core.ml.action.GetMlAutoscalingStats.Request;
14+
15+
import java.io.IOException;
16+
17+
public class GetMlAutoscalingStatsRequestTests extends AbstractWireSerializingTestCase<Request> {
18+
19+
@Override
20+
protected Writeable.Reader<Request> instanceReader() {
21+
return Request::new;
22+
}
23+
24+
@Override
25+
protected Request createTestInstance() {
26+
return new Request(TimeValue.parseTimeValue(randomTimeValue(0, 10_000), "timeout"));
27+
}
28+
29+
@Override
30+
protected Request mutateInstance(Request instance) throws IOException {
31+
return new Request(TimeValue.timeValueMillis(instance.timeout().millis() + randomIntBetween(1, 1000)));
32+
}
33+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.core.ml.action;
9+
10+
import org.elasticsearch.common.io.stream.Writeable;
11+
import org.elasticsearch.test.AbstractWireSerializingTestCase;
12+
import org.elasticsearch.xpack.core.ml.action.GetMlAutoscalingStats.Response;
13+
14+
import java.io.IOException;
15+
16+
import static org.elasticsearch.xpack.core.ml.autoscaling.MlAutoscalingStatsTests.randomAutoscalingResources;
17+
18+
public class GetMlAutoscalingStatsResponseTests extends AbstractWireSerializingTestCase<Response> {
19+
20+
@Override
21+
protected Writeable.Reader<Response> instanceReader() {
22+
return Response::new;
23+
}
24+
25+
@Override
26+
protected Response createTestInstance() {
27+
return new Response(randomAutoscalingResources());
28+
}
29+
30+
@Override
31+
protected Response mutateInstance(Response instance) throws IOException {
32+
return null; // TODO
33+
}
34+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.core.ml.autoscaling;
9+
10+
import org.elasticsearch.common.io.stream.Writeable;
11+
import org.elasticsearch.test.AbstractWireSerializingTestCase;
12+
13+
import java.io.IOException;
14+
15+
public class MlAutoscalingStatsTests extends AbstractWireSerializingTestCase<MlAutoscalingStats> {
16+
17+
public static MlAutoscalingStats randomAutoscalingResources() {
18+
return new MlAutoscalingStats(
19+
randomIntBetween(0, 100), // nodes
20+
randomNonNegativeLong(), // memoryInBytesSum
21+
randomNonNegativeLong(), // modelMemoryInBytes
22+
randomIntBetween(0, 100), // minNodes
23+
randomNonNegativeLong(), // extraSingleNodeModelMemoryInBytes
24+
randomIntBetween(0, 100), // extraSingleNodeProcessors
25+
randomNonNegativeLong(), // extraModelMemoryInBytes
26+
randomIntBetween(0, 100), // extraProcessors
27+
randomNonNegativeLong(), // removeNodeMemoryInBytes
28+
randomNonNegativeLong() // perNodeMemoryOverheadInBytes
29+
);
30+
}
31+
32+
@Override
33+
protected Writeable.Reader<MlAutoscalingStats> instanceReader() {
34+
return MlAutoscalingStats::new;
35+
}
36+
37+
@Override
38+
protected MlAutoscalingStats createTestInstance() {
39+
return randomAutoscalingResources();
40+
}
41+
42+
@Override
43+
protected MlAutoscalingStats mutateInstance(MlAutoscalingStats instance) throws IOException {
44+
return null; // TODO
45+
}
46+
}

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
import org.elasticsearch.xpack.core.ml.action.GetJobModelSnapshotsUpgradeStatsAction;
136136
import org.elasticsearch.xpack.core.ml.action.GetJobsAction;
137137
import org.elasticsearch.xpack.core.ml.action.GetJobsStatsAction;
138+
import org.elasticsearch.xpack.core.ml.action.GetMlAutoscalingStats;
138139
import org.elasticsearch.xpack.core.ml.action.GetModelSnapshotsAction;
139140
import org.elasticsearch.xpack.core.ml.action.GetOverallBucketsAction;
140141
import org.elasticsearch.xpack.core.ml.action.GetRecordsAction;
@@ -237,6 +238,7 @@
237238
import org.elasticsearch.xpack.ml.action.TransportGetJobModelSnapshotsUpgradeStatsAction;
238239
import org.elasticsearch.xpack.ml.action.TransportGetJobsAction;
239240
import org.elasticsearch.xpack.ml.action.TransportGetJobsStatsAction;
241+
import org.elasticsearch.xpack.ml.action.TransportGetMlAutoscalingStats;
240242
import org.elasticsearch.xpack.ml.action.TransportGetModelSnapshotsAction;
241243
import org.elasticsearch.xpack.ml.action.TransportGetOverallBucketsAction;
242244
import org.elasticsearch.xpack.ml.action.TransportGetRecordsAction;
@@ -1415,6 +1417,7 @@ public List<RestHandler> getRestHandlers(
14151417
actionHandlers.add(new ActionHandler<>(SetResetModeAction.INSTANCE, TransportSetResetModeAction.class));
14161418
// Included in this section as it's used by MlMemoryAction
14171419
actionHandlers.add(new ActionHandler<>(TrainedModelCacheInfoAction.INSTANCE, TransportTrainedModelCacheInfoAction.class));
1420+
actionHandlers.add(new ActionHandler<>(GetMlAutoscalingStats.INSTANCE, TransportGetMlAutoscalingStats.class));
14181421
if (machineLearningExtension.get().isAnomalyDetectionEnabled()) {
14191422
actionHandlers.add(new ActionHandler<>(GetJobsAction.INSTANCE, TransportGetJobsAction.class));
14201423
actionHandlers.add(new ActionHandler<>(GetJobsStatsAction.INSTANCE, TransportGetJobsStatsAction.class));

0 commit comments

Comments
 (0)