summaryrefslogtreecommitdiffstats
path: root/node-repository/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'node-repository/src/main/java')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java22
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java7
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java19
4 files changed, 35 insertions, 17 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
index 90133f7499e..98fcd3f56fa 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
@@ -3,9 +3,8 @@ package com.yahoo.vespa.hosted.provision.applications;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.NodeResources;
-import com.yahoo.vespa.hosted.provision.lb.LoadBalancer;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -19,11 +18,15 @@ import java.util.Optional;
*/
public class Cluster {
+ public static final int maxScalingEvents = 15;
+
private final ClusterSpec.Id id;
private final boolean exclusive;
private final ClusterResources min, max;
private final Optional<ClusterResources> suggested;
private final Optional<ClusterResources> target;
+
+ /** The maxScalingEvents last scaling events of this, sorted by increasing time (newest last) */
private final List<ScalingEvent> scalingEvents;
private final String autoscalingStatus;
@@ -45,8 +48,10 @@ public class Cluster {
this.target = Optional.empty();
else
this.target = targetResources;
- this.scalingEvents = scalingEvents;
+ this.scalingEvents = List.copyOf(scalingEvents);
this.autoscalingStatus = autoscalingStatus;
+ if (autoscalingStatus.isEmpty() && targetResources.isPresent())
+ throw new RuntimeException("Autoscaling status set empty for " + id + " even though target is " + targetResources);
}
public ClusterSpec.Id id() { return id; }
@@ -97,8 +102,10 @@ public class Cluster {
}
public Cluster with(ScalingEvent scalingEvent) {
- // NOTE: We're just storing the latest scaling event so far
- return new Cluster(id, exclusive, min, max, suggested, target, List.of(scalingEvent), autoscalingStatus);
+ List<ScalingEvent> scalingEvents = new ArrayList<>(this.scalingEvents);
+ scalingEvents.add(scalingEvent);
+ prune(scalingEvents);
+ return new Cluster(id, exclusive, min, max, suggested, target, scalingEvents, autoscalingStatus);
}
public Cluster withAutoscalingStatus(String autoscalingStatus) {
@@ -120,4 +127,9 @@ public class Cluster {
return "cluster '" + id + "'";
}
+ private void prune(List<ScalingEvent> scalingEvents) {
+ while (scalingEvents.size() > maxScalingEvents)
+ scalingEvents.remove(0);
+ }
+
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
index 3a01e2c7287..66c6d68931c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
@@ -200,6 +200,13 @@ public class Autoscaler {
private static Advice scaleTo(ClusterResources target) {
return new Advice(Optional.of(target), true, "Scaling due to load changes");
}
+
+ @Override
+ public String toString() {
+ return "autoscaling advice: " +
+ (present ? (target.isPresent() ? "Scale to " + target.get() : "Don't scale") : " None");
+ }
+
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java
index 2b4ba3fbbcb..769174a188e 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java
@@ -60,8 +60,8 @@ public class ClusterTimeseries {
List<NodeTimeseries> nodeTimeseries,
NodeRepository nodeRepository) {
Map<String, Instant> startTimePerHost = new HashMap<>();
- if ( ! cluster.scalingEvents().isEmpty()) {
- var deployment = cluster.scalingEvents().get(cluster.scalingEvents().size() - 1);
+ if (cluster.lastScalingEvent().isPresent()) {
+ var deployment = cluster.lastScalingEvent().get();
for (Node node : clusterNodes) {
startTimePerHost.put(node.hostname(), nodeRepository.clock().instant()); // Discard all unless we can prove otherwise
var nodeGenerationMeasurements =
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
index 809c54146d0..1197a01b9c7 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
@@ -14,6 +14,7 @@ import com.yahoo.vespa.hosted.provision.applications.Cluster;
import com.yahoo.vespa.hosted.provision.autoscale.AllocatableClusterResources;
import com.yahoo.vespa.hosted.provision.autoscale.Autoscaler;
import com.yahoo.vespa.hosted.provision.autoscale.MetricsDb;
+import com.yahoo.vespa.orchestrator.status.ApplicationLock;
import java.time.Duration;
import java.util.List;
@@ -66,19 +67,17 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer {
List<Node> clusterNodes,
MaintenanceDeployment deployment) {
Application application = nodeRepository().applications().get(applicationId).orElse(new Application(applicationId));
- Optional<Cluster> cluster = application.cluster(clusterId);
- if (cluster.isEmpty()) return;
+ if (application.cluster(clusterId).isEmpty()) return;
+ Cluster cluster = application.cluster(clusterId).get();
- var advice = autoscaler.autoscale(cluster.get(), clusterNodes);
-
- application = application.with(cluster.get().withAutoscalingStatus(advice.reason()));
+ var advice = autoscaler.autoscale(cluster, clusterNodes);
+ cluster = cluster.withAutoscalingStatus(advice.reason());
if (advice.isEmpty()) {
- applications().put(application, deployment.applicationLock().get());
- }
- else if ( ! cluster.get().targetResources().equals(advice.target())) {
- applications().put(application.with(cluster.get().withTarget(advice.target())), deployment.applicationLock().get());
+ applications().put(application.with(cluster), deployment.applicationLock().get());
+ } else if (!cluster.targetResources().equals(advice.target())) {
+ applications().put(application.with(cluster.withTarget(advice.target())), deployment.applicationLock().get());
if (advice.target().isPresent()) {
- logAutoscaling(advice.target().get(), applicationId, cluster.get(), clusterNodes);
+ logAutoscaling(advice.target().get(), applicationId, cluster, clusterNodes);
deployment.activate();
}
}