diff options
10 files changed, 62 insertions, 24 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java index 07de259be2f..b3317c7f268 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java @@ -77,29 +77,35 @@ public class Cluster { public static class Utilization { - private final double cpu, idealCpu, memory, idealMemory, disk, idealDisk; + private final double cpu, idealCpu, currentCpu, memory, idealMemory, currentMemory, disk, idealDisk, currentDisk; - public Utilization(double cpu, double idealCpu, - double memory, double idealMemory, - double disk, double idealDisk) { + public Utilization(double cpu, double idealCpu, double currentCpu, + double memory, double idealMemory, double currentMemory, + double disk, double idealDisk, double currentDisk) { this.cpu = cpu; this.idealCpu = idealCpu; + this.currentCpu = currentCpu; this.memory = memory; this.idealMemory = idealMemory; + this.currentMemory = currentMemory; this.disk = disk; this.idealDisk = idealDisk; + this.currentDisk = currentDisk; } public double cpu() { return cpu; } public double idealCpu() { return idealCpu; } + public double currentCpu() { return currentCpu; } public double memory() { return memory; } public double idealMemory() { return idealMemory; } + public double currentMemory() { return currentMemory; } public double disk() { return disk; } public double idealDisk() { return idealDisk; } + public double currentDisk() { return currentDisk; } - public static Utilization empty() { return new Utilization(0, 0, 0, 0, 0, 0); } + public static Utilization empty() { return new Utilization(0, 0, 0, 0, 0, 0, 0, 0, 0); } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterUtilizationData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterUtilizationData.java index 0465a1037e8..47cb80a98e2 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterUtilizationData.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterUtilizationData.java @@ -6,8 +6,6 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Cluster; -import java.time.Instant; - /** * Utilization ratios * @@ -21,19 +19,25 @@ public class ClusterUtilizationData { public Double cpu; @JsonProperty("idealCpu") public Double idealCpu; + @JsonProperty("currentCpu") + public Double currentCpu; @JsonProperty("memory") public Double memory; @JsonProperty("idealMemory") public Double idealMemory; + @JsonProperty("currentMemory") + public Double currentMemory; @JsonProperty("disk") public Double disk; @JsonProperty("idealDisk") public Double idealDisk; + @JsonProperty("currentDisk") + public Double currentDisk; public Cluster.Utilization toClusterUtilization() { - return new Cluster.Utilization(cpu, idealCpu, memory, idealMemory, disk, idealDisk); + return new Cluster.Utilization(cpu, idealCpu, currentCpu, memory, idealMemory, currentMemory, disk, idealDisk, currentDisk); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index ae4d891069c..7fcf7554452 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -2092,10 +2092,13 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { private void utilizationToSlime(Cluster.Utilization utilization, Cursor utilizationObject) { utilizationObject.setDouble("cpu", utilization.cpu()); utilizationObject.setDouble("idealCpu", utilization.idealCpu()); + utilizationObject.setDouble("currentCpu", utilization.currentCpu()); utilizationObject.setDouble("memory", utilization.memory()); utilizationObject.setDouble("idealMemory", utilization.idealMemory()); + utilizationObject.setDouble("currentMemory", utilization.currentMemory()); utilizationObject.setDouble("disk", utilization.disk()); utilizationObject.setDouble("idealDisk", utilization.idealDisk()); + utilizationObject.setDouble("currentDisk", utilization.currentDisk()); } private void scalingEventsToSlime(List<Cluster.ScalingEvent> scalingEvents, Cursor scalingEventsArray) { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java index 9e15f2ec788..c3a527a0bd9 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java @@ -117,7 +117,7 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer current, Optional.of(new ClusterResources(2, 1, new NodeResources(3, 8, 50, 1, slow, remote))), Optional.empty(), - new Cluster.Utilization(0.1, 0.2, 0.3, 0.4, 0.5, 0.6), + new Cluster.Utilization(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9), List.of(new Cluster.ScalingEvent(new ClusterResources(0, 0, NodeResources.unspecified()), current, Instant.ofEpochMilli(1234), diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json index 9df83cb2089..cd1fe5acf6a 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json @@ -57,10 +57,13 @@ "utilization": { "cpu": 0.1, "idealCpu": 0.2, - "memory": 0.3, - "idealMemory": 0.4, - "disk": 0.5, - "idealDisk": 0.6 + "currentCpu": 0.3, + "memory": 0.4, + "idealMemory": 0.5, + "currentMemory": 0.6, + "disk": 0.7, + "idealDisk": 0.8, + "currentDisk": 0.9 }, "scalingEvents": [ { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java index f5eb67f0979..e4b85b5317e 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java @@ -19,6 +19,8 @@ import java.util.OptionalDouble; */ public class ClusterModel { + private static final Duration CURRENT_LOAD_DURATION = Duration.ofMinutes(5); + static final double idealQueryCpuLoad = 0.8; static final double idealWriteCpuLoad = 0.95; static final double idealMemoryLoad = 0.7; @@ -96,7 +98,11 @@ public class ClusterModel { return queryFractionOfMax = clusterTimeseries().queryFractionOfMax(scalingDuration(), clock); } - public Load averageLoad() { return nodeTimeseries().averageLoad(); } + /** Returns average load during the last {@link #CURRENT_LOAD_DURATION} */ + public Load currentLoad() { return nodeTimeseries().averageLoad(clock.instant().minus(CURRENT_LOAD_DURATION)); } + + /** Returns average load during the last {@link #scalingDuration()} */ + public Load averageLoad() { return nodeTimeseries().averageLoad(clock.instant().minus(scalingDuration())); } public Load idealLoad() { return new Load(idealCpuLoad(), idealMemoryLoad, idealDiskLoad); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterNodesTimeseries.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterNodesTimeseries.java index a7396f29d92..5f974abd84f 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterNodesTimeseries.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterNodesTimeseries.java @@ -5,6 +5,7 @@ import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.applications.Cluster; import java.time.Duration; +import java.time.Instant; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -42,12 +43,13 @@ public class ClusterNodesTimeseries { /** Returns the number of nodes measured in this */ public int nodesMeasured() { return timeseries.size(); } - /** Returns the average load in this */ - public Load averageLoad() { + /** Returns the average load after the given instant */ + public Load averageLoad(Instant start) { Load total = Load.zero(); int count = 0; for (var nodeTimeseries : timeseries) { for (var snapshot : nodeTimeseries.asList()) { + if (snapshot.at().isBefore(start)) continue; total = total.add(snapshot.load()); count++; } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java index 95909a64b52..380003affb3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java @@ -10,6 +10,7 @@ import com.yahoo.vespa.hosted.provision.applications.Application; import com.yahoo.vespa.hosted.provision.applications.Cluster; import com.yahoo.vespa.hosted.provision.applications.ScalingEvent; import com.yahoo.vespa.hosted.provision.autoscale.ClusterModel; +import com.yahoo.vespa.hosted.provision.autoscale.Load; import com.yahoo.vespa.hosted.provision.autoscale.MetricsDb; import java.net.URI; @@ -85,12 +86,19 @@ public class ApplicationSerializer { } private static void clusterUtilizationToSlime(ClusterModel clusterModel, Cursor utilizationObject) { - utilizationObject.setDouble("cpu", clusterModel.averageLoad().cpu()); - utilizationObject.setDouble("idealCpu", clusterModel.idealLoad().cpu()); - utilizationObject.setDouble("memory", clusterModel.averageLoad().memory()); - utilizationObject.setDouble("idealMemory", clusterModel.idealLoad().memory()); - utilizationObject.setDouble("disk", clusterModel.averageLoad().disk()); - utilizationObject.setDouble("idealDisk", clusterModel.idealLoad().disk()); + Load idealLoad = clusterModel.idealLoad(); + Load averageLoad = clusterModel.averageLoad(); + Load currentLoad = clusterModel.currentLoad(); + + utilizationObject.setDouble("cpu", averageLoad.cpu()); + utilizationObject.setDouble("idealCpu", idealLoad.cpu()); + utilizationObject.setDouble("currentCpu", currentLoad.cpu()); + utilizationObject.setDouble("memory", averageLoad.memory()); + utilizationObject.setDouble("idealMemory", idealLoad.memory()); + utilizationObject.setDouble("currentMemory", currentLoad.memory()); + utilizationObject.setDouble("disk", averageLoad.disk()); + utilizationObject.setDouble("idealDisk", idealLoad.disk()); + utilizationObject.setDouble("currentDisk", currentLoad.disk()); } private static void scalingEventsToSlime(List<ScalingEvent> scalingEvents, Cursor scalingEventsArray) { diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json index 65e07c46242..1083930e294 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json @@ -67,10 +67,13 @@ "utilization" : { "cpu" : 0.0, "idealCpu": 0.275, + "currentCpu": 0.0, "memory" : 0.0, "idealMemory": 0.7, + "currentMemory": 0.0, "disk" : 0.0, - "idealDisk": 0.6 + "idealDisk": 0.6, + "currentDisk": 0.0 }, "scalingEvents" : [ { diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json index ecab55d19d4..61e0569d349 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json @@ -43,10 +43,13 @@ "utilization" : { "cpu" : 0.0, "idealCpu": 0.2664285714285714, + "currentCpu": 0.0, "memory" : 0.0, "idealMemory": 0.7, + "currentMemory": 0.0, "disk" : 0.0, - "idealDisk": 0.6 + "idealDisk": 0.6, + "currentDisk": 0.0 }, "scalingEvents" : [ { |