aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHÃ¥kon Hallingstad <hakon@verizonmedia.com>2021-11-30 17:07:17 +0100
committerGitHub <noreply@github.com>2021-11-30 17:07:17 +0100
commitaa3ffac0caaba2c60fabc585be8376cfe132c17d (patch)
tree9b150af98aa9dfff7d552b5c63698d49d48e7805
parent318edd10866b25b06419ed6069227eafbe63d685 (diff)
parent612cba5886325c1b6ed627d7ca35fa2a2511e625 (diff)
Merge pull request #20302 from vespa-engine/revert-20298-bratseth/autoscaling-in-devv7.508.20
Revert "Account for capacity policies when autoscaling"
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java9
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java33
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java26
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java10
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java157
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java18
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModelTest.java14
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java4
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java4
15 files changed, 102 insertions, 209 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java
index df5044de05c..3c2ab8cead2 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java
@@ -2,9 +2,10 @@
package com.yahoo.vespa.hosted.provision.applications;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.Capacity;
+import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Optional;
@@ -58,12 +59,12 @@ public class Application {
* Returns an application with the given cluster having the min and max resource limits of the given cluster.
* If the cluster has a target which is not inside the new limits, the target is removed.
*/
- public Application withCluster(ClusterSpec.Id id, boolean exclusive, Capacity requested) {
+ public Application withCluster(ClusterSpec.Id id, boolean exclusive, ClusterResources min, ClusterResources max) {
Cluster cluster = clusters.get(id);
if (cluster == null)
- cluster = Cluster.create(id, exclusive, requested);
+ cluster = new Cluster(id, exclusive, min, max, Optional.empty(), Optional.empty(), List.of(), AutoscalingStatus.empty());
else
- cluster = cluster.withConfiguration(exclusive, requested);
+ cluster = cluster.withConfiguration(exclusive, min, max);
return with(cluster);
}
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 e0ccbe10b10..5478999e4fe 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
@@ -1,7 +1,6 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.applications;
-import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.hosted.provision.autoscale.Autoscaler;
@@ -26,7 +25,6 @@ public class Cluster {
private final ClusterSpec.Id id;
private final boolean exclusive;
private final ClusterResources min, max;
- private boolean required;
private final Optional<Suggestion> suggested;
private final Optional<ClusterResources> target;
@@ -38,7 +36,6 @@ public class Cluster {
boolean exclusive,
ClusterResources minResources,
ClusterResources maxResources,
- boolean required,
Optional<Suggestion> suggestedResources,
Optional<ClusterResources> targetResources,
List<ScalingEvent> scalingEvents,
@@ -47,7 +44,6 @@ public class Cluster {
this.exclusive = exclusive;
this.min = Objects.requireNonNull(minResources);
this.max = Objects.requireNonNull(maxResources);
- this.required = required;
this.suggested = Objects.requireNonNull(suggestedResources);
Objects.requireNonNull(targetResources);
if (targetResources.isPresent() && ! targetResources.get().isWithin(minResources, maxResources))
@@ -60,20 +56,14 @@ public class Cluster {
public ClusterSpec.Id id() { return id; }
- /** Returns whether the nodes allocated to this cluster must be on host exclusively dedicated to this application */
- public boolean exclusive() { return exclusive; }
-
/** Returns the configured minimal resources in this cluster */
public ClusterResources minResources() { return min; }
/** Returns the configured maximal resources in this cluster */
public ClusterResources maxResources() { return max; }
- /**
- * Returns whether the resources of this cluster are required to be within the specified min and max.
- * Otherwise they may be adjusted by capacity policies.
- */
- public boolean required() { return required; }
+ /** Returns whether the nodes allocated to this cluster must be on host exclusively dedicated to this application */
+ public boolean exclusive() { return exclusive; }
/**
* Returns the computed resources (between min and max, inclusive) this cluster should
@@ -107,18 +97,16 @@ public class Cluster {
/** The latest autoscaling status of this cluster, or unknown (never null) if none */
public AutoscalingStatus autoscalingStatus() { return autoscalingStatus; }
- public Cluster withConfiguration(boolean exclusive, Capacity capacity) {
- return new Cluster(id, exclusive,
- capacity.minResources(), capacity.maxResources(), capacity.isRequired(),
- suggested, target, scalingEvents, autoscalingStatus);
+ public Cluster withConfiguration(boolean exclusive, ClusterResources min, ClusterResources max) {
+ return new Cluster(id, exclusive, min, max, suggested, target, scalingEvents, autoscalingStatus);
}
public Cluster withSuggested(Optional<Suggestion> suggested) {
- return new Cluster(id, exclusive, min, max, required, suggested, target, scalingEvents, autoscalingStatus);
+ return new Cluster(id, exclusive, min, max, suggested, target, scalingEvents, autoscalingStatus);
}
public Cluster withTarget(Optional<ClusterResources> target) {
- return new Cluster(id, exclusive, min, max, required, suggested, target, scalingEvents, autoscalingStatus);
+ return new Cluster(id, exclusive, min, max, suggested, target, scalingEvents, autoscalingStatus);
}
/** Add or update (based on "at" time) a scaling event */
@@ -132,12 +120,12 @@ public class Cluster {
scalingEvents.add(scalingEvent);
prune(scalingEvents);
- return new Cluster(id, exclusive, min, max, required, suggested, target, scalingEvents, autoscalingStatus);
+ return new Cluster(id, exclusive, min, max, suggested, target, scalingEvents, autoscalingStatus);
}
public Cluster with(AutoscalingStatus autoscalingStatus) {
if (autoscalingStatus.equals(this.autoscalingStatus)) return this;
- return new Cluster(id, exclusive, min, max, required, suggested, target, scalingEvents, autoscalingStatus);
+ return new Cluster(id, exclusive, min, max, suggested, target, scalingEvents, autoscalingStatus);
}
@Override
@@ -168,11 +156,6 @@ public class Cluster {
return -1;
}
- public static Cluster create(ClusterSpec.Id id, boolean exclusive, Capacity requested) {
- return new Cluster(id, exclusive, requested.minResources(), requested.maxResources(), requested.isRequired(),
- Optional.empty(), Optional.empty(), List.of(), AutoscalingStatus.empty());
- }
-
public static class Suggestion {
private final ClusterResources resources;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
index 078b0621a99..f1e707be7b4 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
@@ -8,7 +8,6 @@ import com.yahoo.config.provision.NodeResources;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
import com.yahoo.vespa.hosted.provision.NodeRepository;
-import com.yahoo.vespa.hosted.provision.provisioning.CapacityPolicies;
import com.yahoo.vespa.hosted.provision.provisioning.NodeResourceLimits;
import java.util.List;
@@ -55,14 +54,14 @@ public class AllocatableClusterResources {
public AllocatableClusterResources(ClusterResources realResources,
NodeResources advertisedResources,
- ClusterResources idealResources,
+ NodeResources idealResources,
ClusterSpec clusterSpec) {
this.nodes = realResources.nodes();
this.groups = realResources.groups();
this.realResources = realResources.nodeResources();
this.advertisedResources = advertisedResources;
this.clusterSpec = clusterSpec;
- this.fulfilment = fulfilment(realResources, idealResources);
+ this.fulfilment = fulfilment(realResources.nodeResources(), idealResources);
}
/**
@@ -100,10 +99,10 @@ public class AllocatableClusterResources {
*/
public double fulfilment() { return fulfilment; }
- private static double fulfilment(ClusterResources realResources, ClusterResources idealResources) {
- double vcpuFulfilment = Math.min(1, realResources.totalResources().vcpu() / idealResources.totalResources().vcpu());
- double memoryGbFulfilment = Math.min(1, realResources.totalResources().memoryGb() / idealResources.totalResources().memoryGb());
- double diskGbFulfilment = Math.min(1, realResources.totalResources().diskGb() / idealResources.totalResources().diskGb());
+ private static double fulfilment(NodeResources realResources, NodeResources idealResources) {
+ double vcpuFulfilment = Math.min(1, realResources.vcpu() / idealResources.vcpu());
+ double memoryGbFulfilment = Math.min(1, realResources.memoryGb() / idealResources.memoryGb());
+ double diskGbFulfilment = Math.min(1, realResources.diskGb() / idealResources.diskGb());
return (vcpuFulfilment + memoryGbFulfilment + diskGbFulfilment) / 3;
}
@@ -139,25 +138,21 @@ public class AllocatableClusterResources {
public static Optional<AllocatableClusterResources> from(ClusterResources wantedResources,
ClusterSpec clusterSpec,
Limits applicationLimits,
- boolean required,
NodeList hosts,
NodeRepository nodeRepository) {
- var capacityPolicies = new CapacityPolicies(nodeRepository);
var systemLimits = new NodeResourceLimits(nodeRepository);
boolean exclusive = clusterSpec.isExclusive();
- int actualNodes = capacityPolicies.decideSize(wantedResources.nodes(), required, true, false, clusterSpec);
if ( !clusterSpec.isExclusive() && !nodeRepository.zone().getCloud().dynamicProvisioning()) {
// We decide resources: Add overhead to what we'll request (advertised) to make sure real becomes (at least) cappedNodeResources
var advertisedResources = nodeRepository.resourcesCalculator().realToRequest(wantedResources.nodeResources(), exclusive);
advertisedResources = systemLimits.enlargeToLegal(advertisedResources, clusterSpec.type(), exclusive); // Ask for something legal
advertisedResources = applicationLimits.cap(advertisedResources); // Overrides other conditions, even if it will then fail
- advertisedResources = capacityPolicies.decideNodeResources(advertisedResources, required, clusterSpec); // Adjust to what we can request
var realResources = nodeRepository.resourcesCalculator().requestToReal(advertisedResources, exclusive); // What we'll really get
if ( ! systemLimits.isWithinRealLimits(realResources, clusterSpec.type())) return Optional.empty();
if (matchesAny(hosts, advertisedResources))
- return Optional.of(new AllocatableClusterResources(wantedResources.withNodes(actualNodes).with(realResources),
+ return Optional.of(new AllocatableClusterResources(wantedResources.with(realResources),
advertisedResources,
- wantedResources,
+ wantedResources.nodeResources(),
clusterSpec));
else
return Optional.empty();
@@ -168,7 +163,6 @@ public class AllocatableClusterResources {
for (Flavor flavor : nodeRepository.flavors().getFlavors()) {
// Flavor decide resources: Real resources are the worst case real resources we'll get if we ask for these advertised resources
NodeResources advertisedResources = nodeRepository.resourcesCalculator().advertisedResourcesOf(flavor);
- advertisedResources = capacityPolicies.decideNodeResources(advertisedResources, required, clusterSpec); // Adjust to what we can get
NodeResources realResources = nodeRepository.resourcesCalculator().requestToReal(advertisedResources, exclusive);
// Adjust where we don't need exact match to the flavor
@@ -184,9 +178,9 @@ public class AllocatableClusterResources {
if ( ! between(applicationLimits.min().nodeResources(), applicationLimits.max().nodeResources(), advertisedResources)) continue;
if ( ! systemLimits.isWithinRealLimits(realResources, clusterSpec.type())) continue;
- var candidate = new AllocatableClusterResources(wantedResources.withNodes(actualNodes).with(realResources),
+ var candidate = new AllocatableClusterResources(wantedResources.with(realResources),
advertisedResources,
- wantedResources,
+ wantedResources.nodeResources(),
clusterSpec);
if (best.isEmpty() || candidate.preferableTo(best.get()))
best = Optional.of(candidate);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java
index b8a80a9bd2b..6fd9801164a 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java
@@ -65,9 +65,7 @@ public class AllocationOptimizer {
nodeResourcesWith(nodesAdjustedForRedundancy,
groupsAdjustedForRedundancy,
limits, target, current, clusterModel));
- var allocatableResources = AllocatableClusterResources.from(next, current.clusterSpec(), limits,
- clusterModel.cluster().required(),
- hosts, nodeRepository);
+ var allocatableResources = AllocatableClusterResources.from(next, current.clusterSpec(), limits, hosts, nodeRepository);
if (allocatableResources.isEmpty()) continue;
if (bestAllocation.isEmpty() || allocatableResources.get().preferableTo(bestAllocation.get()))
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 1001ab83cc0..35aafd3e0f4 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
@@ -32,7 +32,6 @@ public class ClusterModel {
static final double idealDiskLoad = 0.6;
private final Application application;
- private final Cluster cluster;
/** The current nodes of this cluster, or empty if this models a new cluster not yet deployed */
private final NodeList nodes;
private final Clock clock;
@@ -51,7 +50,6 @@ public class ClusterModel {
MetricsDb metricsDb,
Clock clock) {
this.application = application;
- this.cluster = cluster;
this.nodes = clusterNodes;
this.clock = clock;
this.scalingDuration = computeScalingDuration(cluster, clusterSpec);
@@ -67,7 +65,6 @@ public class ClusterModel {
ClusterTimeseries clusterTimeseries,
ClusterNodesTimeseries nodeTimeseries) {
this.application = application;
- this.cluster = cluster;
this.nodes = null;
this.clock = clock;
@@ -76,8 +73,6 @@ public class ClusterModel {
this.nodeTimeseries = nodeTimeseries;
}
- public Cluster cluster() { return cluster; }
-
/** Returns the predicted duration of a rescaling of this cluster */
public Duration scalingDuration() { return scalingDuration; }
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java
index 2289ba4a0ea..9cdb4c69b97 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java
@@ -48,7 +48,6 @@ public class ApplicationSerializer {
private static final String exclusiveKey = "exclusive";
private static final String minResourcesKey = "min";
private static final String maxResourcesKey = "max";
- private static final String requiredKey = "required";
private static final String suggestedKey = "suggested";
private static final String resourcesKey = "resources";
private static final String targetResourcesKey = "target";
@@ -100,6 +99,7 @@ public class ApplicationSerializer {
}
private static Status statusFromSlime(Inspector statusObject) {
+ if ( ! statusObject.valid()) return Status.initial(); // TODO: Remove this line after March 2021
return new Status(statusObject.field(currentReadShareKey).asDouble(),
statusObject.field(maxReadShareKey).asDouble());
}
@@ -118,7 +118,6 @@ public class ApplicationSerializer {
clusterObject.setBool(exclusiveKey, cluster.exclusive());
toSlime(cluster.minResources(), clusterObject.setObject(minResourcesKey));
toSlime(cluster.maxResources(), clusterObject.setObject(maxResourcesKey));
- clusterObject.setBool(requiredKey, cluster.required());
cluster.suggestedResources().ifPresent(suggested -> toSlime(suggested, clusterObject.setObject(suggestedKey)));
cluster.targetResources().ifPresent(target -> toSlime(target, clusterObject.setObject(targetResourcesKey)));
scalingEventsToSlime(cluster.scalingEvents(), clusterObject.setArray(scalingEventsKey));
@@ -131,7 +130,6 @@ public class ApplicationSerializer {
clusterObject.field(exclusiveKey).asBool(),
clusterResourcesFromSlime(clusterObject.field(minResourcesKey)),
clusterResourcesFromSlime(clusterObject.field(maxResourcesKey)),
- clusterObject.field(requiredKey).asBool(),
optionalSuggestionFromSlime(clusterObject.field(suggestedKey)),
optionalClusterResourcesFromSlime(clusterObject.field(targetResourcesKey)),
scalingEventsFromSlime(clusterObject.field(scalingEventsKey)),
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
index 0c2c3c48df1..839bc21827c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
@@ -29,11 +29,11 @@ public class CapacityPolicies {
this.sharedHosts = type -> PermanentFlags.SHARED_HOST.bindTo(nodeRepository.flagSource()).value().isEnabled(type.name());
}
- public int decideSize(int requested, boolean required, boolean canFail, boolean isTester, ClusterSpec cluster) {
- if (isTester) return 1;
+ public int decideSize(int requested, Capacity capacity, ClusterSpec cluster, ApplicationId application) {
+ if (application.instance().isTester()) return 1;
- ensureRedundancy(requested, cluster, canFail);
- if (required) return requested;
+ ensureRedundancy(requested, cluster, capacity.canFail());
+ if (capacity.isRequired()) return requested;
switch(zone.environment()) {
case dev : case test : return 1;
case perf : return Math.min(requested, 3);
@@ -43,11 +43,11 @@ public class CapacityPolicies {
}
}
- public NodeResources decideNodeResources(NodeResources target, boolean required, ClusterSpec cluster) {
+ public NodeResources decideNodeResources(NodeResources target, Capacity capacity, ClusterSpec cluster) {
if (target.isUnspecified())
target = defaultNodeResources(cluster.type());
- if (required) return target;
+ if (capacity.isRequired()) return target;
// Dev does not cap the cpu or network of containers since usage is spotty: Allocate just a small amount exclusively
if (zone.environment() == Environment.dev && !zone.getCloud().dynamicProvisioning())
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
index b35b0a5e301..0ab04a1a73d 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
@@ -97,13 +97,9 @@ public class NodeRepositoryProvisioner implements Provisioner {
NodeSpec nodeSpec;
if (requested.type() == NodeType.tenant) {
ClusterResources target = decideTargetResources(application, cluster, requested);
- int nodeCount = capacityPolicies.decideSize(target.nodes(),
- requested.isRequired(),
- requested.canFail(),
- application.instance().isTester(),
- cluster);
+ int nodeCount = capacityPolicies.decideSize(target.nodes(), requested, cluster, application);
groups = Math.min(target.groups(), nodeCount); // cannot have more groups than nodes
- resources = capacityPolicies.decideNodeResources(target.nodeResources(), requested.isRequired(), cluster);
+ resources = capacityPolicies.decideNodeResources(target.nodeResources(), requested, cluster);
boolean exclusive = capacityPolicies.decideExclusivity(requested, cluster.isExclusive());
nodeSpec = NodeSpec.from(nodeCount, resources, exclusive, requested.canFail());
logIfDownscaled(target.nodes(), nodeCount, cluster, logger);
@@ -145,7 +141,7 @@ public class NodeRepositoryProvisioner implements Provisioner {
private ClusterResources decideTargetResources(ApplicationId applicationId, ClusterSpec clusterSpec, Capacity requested) {
try (Mutex lock = nodeRepository.nodes().lock(applicationId)) {
var application = nodeRepository.applications().get(applicationId).orElse(Application.empty(applicationId))
- .withCluster(clusterSpec.id(), clusterSpec.isExclusive(), requested);
+ .withCluster(clusterSpec.id(), clusterSpec.isExclusive(), requested.minResources(), requested.maxResources());
nodeRepository.applications().put(application, lock);
var cluster = application.cluster(clusterSpec.id()).get();
return cluster.targetResources().orElseGet(() -> currentResources(application, clusterSpec, cluster, requested));
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java
index 667dffef2a6..4a0c2012ae4 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java
@@ -2,7 +2,6 @@
package com.yahoo.vespa.hosted.provision.autoscale;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostSpec;
@@ -56,7 +55,7 @@ public class AutoscalingIntegrationTest {
ClusterResources max = new ClusterResources(2, 1, nodes);
Application application = tester.nodeRepository().applications().get(application1).orElse(Application.empty(application1))
- .withCluster(cluster1.id(), false, Capacity.from(min, max));
+ .withCluster(cluster1.id(), false, min, max);
try (Mutex lock = tester.nodeRepository().nodes().lock(application1)) {
tester.nodeRepository().applications().put(application, lock);
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
index 601a7109533..a3c7b7d2d2b 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
@@ -41,7 +41,6 @@ public class AutoscalingTest {
new NodeResources(1, 1, 1, 1, NodeResources.DiskSpeed.any));
ClusterResources max = new ClusterResources(20, 1,
new NodeResources(100, 1000, 1000, 1, NodeResources.DiskSpeed.any));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(hostResources);
ApplicationId application1 = tester.applicationId("application1");
@@ -51,10 +50,10 @@ public class AutoscalingTest {
tester.deploy(application1, cluster1, 5, 1, hostResources);
tester.clock().advance(Duration.ofDays(1));
- assertTrue("No measurements -> No change", tester.autoscale(application1, cluster1.id(), capacity).isEmpty());
+ assertTrue("No measurements -> No change", tester.autoscale(application1, cluster1.id(), min, max).isEmpty());
tester.addCpuMeasurements(0.25f, 1f, 59, application1);
- assertTrue("Too few measurements -> No change", tester.autoscale(application1, cluster1.id(), capacity).isEmpty());
+ assertTrue("Too few measurements -> No change", tester.autoscale(application1, cluster1.id(), min, max).isEmpty());
tester.clock().advance(Duration.ofDays(1));
tester.addCpuMeasurements(0.25f, 1f, 120, application1);
@@ -62,10 +61,10 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
ClusterResources scaledResources = tester.assertResources("Scaling up since resource usage is too high",
15, 1, 1.2, 28.6, 28.6,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.deploy(application1, cluster1, scaledResources);
- assertTrue("Cluster in flux -> No further change", tester.autoscale(application1, cluster1.id(), capacity).isEmpty());
+ assertTrue("Cluster in flux -> No further change", tester.autoscale(application1, cluster1.id(), min, max).isEmpty());
tester.deactivateRetired(application1, cluster1, scaledResources);
@@ -74,19 +73,19 @@ public class AutoscalingTest {
tester.clock().advance(Duration.ofMinutes(-10 * 5));
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
assertTrue("Load change is large, but insufficient measurements for new config -> No change",
- tester.autoscale(application1, cluster1.id(), capacity).isEmpty());
+ tester.autoscale(application1, cluster1.id(), min, max).isEmpty());
tester.addCpuMeasurements(0.19f, 1f, 100, application1);
tester.clock().advance(Duration.ofMinutes(-10 * 5));
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
- assertEquals("Load change is small -> No change", Optional.empty(), tester.autoscale(application1, cluster1.id(), capacity).target());
+ assertEquals("Load change is small -> No change", Optional.empty(), tester.autoscale(application1, cluster1.id(), min, max).target());
tester.addCpuMeasurements(0.1f, 1f, 120, application1);
tester.clock().advance(Duration.ofMinutes(-10 * 5));
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling down to minimum since usage has gone down significantly",
7, 1, 1.0, 66.7, 66.7,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
var events = tester.nodeRepository().applications().get(application1).get().cluster(cluster1.id()).get().scalingEvents();
}
@@ -97,7 +96,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 1, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -110,7 +108,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
ClusterResources scaledResources = tester.assertResources("Scaling up since cpu usage is too high",
7, 1, 2.5, 80.0, 80.0,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.deploy(application1, cluster1, scaledResources);
tester.deactivateRetired(application1, cluster1, scaledResources);
@@ -120,7 +118,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling down since cpu usage has gone down",
4, 1, 2.5, 68.6, 68.6,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -144,10 +142,9 @@ public class AutoscalingTest {
new NodeResources(1, 1, 1, 1, NodeResources.DiskSpeed.any));
ClusterResources max = new ClusterResources(20, 1,
new NodeResources(100, 1000, 1000, 1, NodeResources.DiskSpeed.any));
- var capacity = Capacity.from(min, max);
ClusterResources scaledResources = tester.assertResources("Scaling up since resource usage is too high",
14, 1, 1.4, 30.8, 30.8,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
assertEquals("Disk speed from min/max is used",
NodeResources.DiskSpeed.any, scaledResources.nodeResources().diskSpeed());
tester.deploy(application1, cluster1, scaledResources);
@@ -167,7 +164,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(1, 10, 10, 1);
var min = new ClusterResources( 2, 1, resources.with(NodeResources.DiskSpeed.any));
var max = new ClusterResources( 10, 1, resources.with(NodeResources.DiskSpeed.any));
- var capacity = Capacity.from(min, max);
tester.deploy(application1, cluster1, Capacity.from(min, max));
// Redeployment without target: Uses current resource numbers with *requested* non-numbers (i.e disk-speed any)
@@ -180,7 +176,7 @@ public class AutoscalingTest {
// Autoscaling: Uses disk-speed any as well
tester.clock().advance(Duration.ofDays(2));
tester.addCpuMeasurements(0.8f, 1f, 120, application1);
- Autoscaler.Advice advice = tester.autoscale(application1, cluster1.id(), capacity);
+ Autoscaler.Advice advice = tester.autoscale(application1, cluster1.id(), min, max);
assertEquals(NodeResources.DiskSpeed.any, advice.target().get().nodeResources().diskSpeed());
@@ -191,7 +187,6 @@ public class AutoscalingTest {
NodeResources hostResources = new NodeResources(6, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources( 6, 1, new NodeResources(2.4, 78, 79, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(hostResources);
ApplicationId application1 = tester.applicationId("application1");
@@ -205,7 +200,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling up to limit since resource usage is too high",
6, 1, 2.4, 78.0, 79.0,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -213,7 +208,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 4, 1, new NodeResources(1.8, 7.4, 8.5, 1));
ClusterResources max = new ClusterResources( 6, 1, new NodeResources(2.4, 78, 79, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -224,7 +218,7 @@ public class AutoscalingTest {
tester.addMeasurements(0.05f, 0.05f, 0.05f, 0, 120, application1);
tester.assertResources("Scaling down to limit since resource usage is low",
4, 1, 1.8, 7.7, 10.0,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -232,7 +226,6 @@ public class AutoscalingTest {
NodeResources hostResources = new NodeResources(6, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, NodeResources.unspecified());
ClusterResources max = new ClusterResources( 6, 1, NodeResources.unspecified());
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(hostResources);
ApplicationId application1 = tester.applicationId("application1");
@@ -251,7 +244,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling up to limit since resource usage is too high",
4, 1, defaultResources,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -259,7 +252,6 @@ public class AutoscalingTest {
NodeResources hostResources = new NodeResources(30.0, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 2, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(18, 6, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(hostResources);
ApplicationId application1 = tester.applicationId("application1");
@@ -272,7 +264,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling up since resource usage is too high",
6, 6, 3.6, 8.0, 10.0,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -280,7 +272,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = min;
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources);
ApplicationId application1 = tester.applicationId("application1");
@@ -290,13 +281,13 @@ public class AutoscalingTest {
tester.deploy(application1, cluster1, 5, 1, resources);
tester.clock().advance(Duration.ofDays(1));
tester.addCpuMeasurements(0.25f, 1f, 120, application1);
- assertTrue(tester.autoscale(application1, cluster1.id(), capacity).isEmpty());
+ assertTrue(tester.autoscale(application1, cluster1.id(), min, max).isEmpty());
}
@Test
public void prefers_remote_disk_when_no_local_match() {
- NodeResources resources = new NodeResources(3, 100, 50, 1);
- ClusterResources min = new ClusterResources( 2, 1, resources);
+ NodeResources resources = new NodeResources(3, 100, 100, 1);
+ ClusterResources min = new ClusterResources( 2, 1, new NodeResources(3, 100, 50, 1));
ClusterResources max = min;
// AutoscalingTester hardcodes 3Gb memory overhead:
Flavor localFlavor = new Flavor("local", new NodeResources(3, 97, 75, 1, DiskSpeed.fast, StorageType.local));
@@ -350,7 +341,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources(2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(5, 1, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -360,7 +350,7 @@ public class AutoscalingTest {
tester.deploy(application1, cluster1, 2, 1, resources);
tester.addMeasurements(0.5f, 0.6f, 0.7f, 1, false, true, 120, application1);
assertTrue("Not scaling up since nodes were measured while cluster was unstable",
- tester.autoscale(application1, cluster1.id(), capacity).isEmpty());
+ tester.autoscale(application1, cluster1.id(), min, max).isEmpty());
}
@Test
@@ -368,7 +358,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources(2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(5, 1, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -378,7 +367,7 @@ public class AutoscalingTest {
tester.deploy(application1, cluster1, 2, 1, resources);
tester.addMeasurements(0.5f, 0.6f, 0.7f, 1, true, false, 120, application1);
assertTrue("Not scaling up since nodes were measured while cluster was unstable",
- tester.autoscale(application1, cluster1.id(), capacity).isEmpty());
+ tester.autoscale(application1, cluster1.id(), min, max).isEmpty());
}
@Test
@@ -386,7 +375,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 2, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 20, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -399,7 +387,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling up since resource usage is too high",
7, 7, 2.5, 80.0, 80.0,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -407,7 +395,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 3, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(21, 7, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -422,7 +409,7 @@ public class AutoscalingTest {
t -> 1.0);
tester.assertResources("Scaling up since resource usage is too high, changing to 1 group is cheaper",
8, 1, 2.6, 83.3, 83.3,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
/** Same as above but mostly write traffic, which favors smaller groups */
@@ -431,7 +418,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 3, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(21, 7, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -446,15 +432,14 @@ public class AutoscalingTest {
t -> 100.0);
tester.assertResources("Scaling down since resource usage is too high, changing to 1 group is cheaper",
4, 1, 2.1, 83.3, 83.3,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
public void test_autoscaling_group_size() {
NodeResources hostResources = new NodeResources(100, 1000, 1000, 100);
- ClusterResources min = new ClusterResources( 2, 2, new NodeResources(1, 1, 1, 1));
+ ClusterResources min = new ClusterResources( 3, 2, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(30, 30, new NodeResources(100, 100, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(hostResources);
ApplicationId application1 = tester.applicationId("application1");
@@ -468,7 +453,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Increase group size to reduce memory load",
8, 2, 12.4, 96.2, 62.5,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -476,7 +461,6 @@ public class AutoscalingTest {
NodeResources hostResources = new NodeResources(6, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 1, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(hostResources);
ApplicationId application1 = tester.applicationId("application1");
@@ -489,7 +473,7 @@ public class AutoscalingTest {
tester.addMemMeasurements(0.02f, 0.95f, 120, application1);
tester.assertResources("Scaling down",
6, 1, 2.9, 4.0, 95.0,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -497,7 +481,6 @@ public class AutoscalingTest {
NodeResources hostResources = new NodeResources(6, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 1, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(hostResources);
ApplicationId application1 = tester.applicationId("application1");
@@ -509,7 +492,7 @@ public class AutoscalingTest {
tester.addMemMeasurements(0.02f, 0.95f, 120, application1);
tester.clock().advance(Duration.ofMinutes(-10 * 5));
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
- assertTrue(tester.autoscale(application1, cluster1.id(), capacity).target().isEmpty());
+ assertTrue(tester.autoscale(application1, cluster1.id(), min, max).target().isEmpty());
// Trying the same later causes autoscaling
tester.clock().advance(Duration.ofDays(2));
@@ -518,7 +501,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling down",
6, 1, 1.4, 4.0, 95.0,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -526,11 +509,9 @@ public class AutoscalingTest {
NodeResources hostResources = new NodeResources(60, 100, 1000, 10);
ClusterResources min = new ClusterResources(2, 1, new NodeResources( 2, 20, 200, 1));
ClusterResources max = new ClusterResources(4, 1, new NodeResources(60, 100, 1000, 1));
- var capacity = Capacity.from(min, max);
{ // No memory tax
- AutoscalingTester tester = new AutoscalingTester(Environment.prod, hostResources,
- new OnlySubtractingWhenForecastingCalculator(0));
+ AutoscalingTester tester = new AutoscalingTester(hostResources, new OnlySubtractingWhenForecastingCalculator(0));
ApplicationId application1 = tester.applicationId("app1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.content, "cluster1");
@@ -541,12 +522,11 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling up",
4, 1, 6.7, 20.5, 200,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
{ // 15 Gb memory tax
- AutoscalingTester tester = new AutoscalingTester(Environment.prod, hostResources,
- new OnlySubtractingWhenForecastingCalculator(15));
+ AutoscalingTester tester = new AutoscalingTester(hostResources, new OnlySubtractingWhenForecastingCalculator(15));
ApplicationId application1 = tester.applicationId("app1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.content, "cluster1");
@@ -557,7 +537,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling up",
4, 1, 6.7, 35.5, 200,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
}
@@ -565,7 +545,6 @@ public class AutoscalingTest {
public void test_autoscaling_with_dynamic_provisioning() {
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 1, new NodeResources(100, 1000, 1000, 1));
- var capacity = Capacity.from(min, max);
List<Flavor> flavors = new ArrayList<>();
flavors.add(new Flavor("aws-xlarge", new NodeResources(3, 200, 100, 1, NodeResources.DiskSpeed.fast, NodeResources.StorageType.remote)));
flavors.add(new Flavor("aws-large", new NodeResources(3, 150, 100, 1, NodeResources.DiskSpeed.fast, NodeResources.StorageType.remote)));
@@ -588,7 +567,7 @@ public class AutoscalingTest {
tester.addMemMeasurements(0.9f, 0.6f, 120, application1);
ClusterResources scaledResources = tester.assertResources("Scaling up since resource usage is too high.",
8, 1, 3, 83, 34.3,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.deploy(application1, cluster1, scaledResources);
tester.deactivateRetired(application1, cluster1, scaledResources);
@@ -599,7 +578,7 @@ public class AutoscalingTest {
tester.addQueryRateMeasurements(application1, cluster1.id(), 10, t -> t == 0 ? 20.0 : 10.0); // Query traffic only
tester.assertResources("Scaling down since resource usage has gone down",
5, 1, 3, 83, 36.0,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -607,7 +586,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 1, 1, resources);
ClusterResources max = new ClusterResources(10, 1, resources);
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -621,17 +599,17 @@ public class AutoscalingTest {
// (no read share stored)
tester.assertResources("Advice to scale up since we set aside for bcp by default",
7, 1, 3, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.storeReadShare(0.25, 0.5, application1);
tester.assertResources("Half of global share is the same as the default assumption used above",
7, 1, 3, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.storeReadShare(0.5, 0.5, application1);
tester.assertResources("Advice to scale down since we don't need room for bcp",
4, 1, 3, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@@ -642,7 +620,6 @@ public class AutoscalingTest {
NodeResources maxResources = new NodeResources(10, 100, 100, 1);
ClusterResources min = new ClusterResources(5, 1, minResources);
ClusterResources max = new ClusterResources(5, 1, maxResources);
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(maxResources.withVcpu(maxResources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -656,7 +633,7 @@ public class AutoscalingTest {
// (no query rate data)
tester.assertResources("Scale up since we assume we need 2x cpu for growth when no data scaling time data",
5, 1, 6.3, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.setScalingDuration(application1, cluster1.id(), Duration.ofMinutes(5));
tester.addQueryRateMeasurements(application1, cluster1.id(),
@@ -666,7 +643,7 @@ public class AutoscalingTest {
tester.addCpuMeasurements(0.25f, 1f, 100, application1);
tester.assertResources("Scale down since observed growth is slower than scaling time",
5, 1, 3.4, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.clearQueryRateMeasurements(application1, cluster1.id());
@@ -678,7 +655,7 @@ public class AutoscalingTest {
tester.addCpuMeasurements(0.25f, 1f, 100, application1);
tester.assertResources("Scale up since observed growth is faster than scaling time",
5, 1, 10.0, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -688,7 +665,6 @@ public class AutoscalingTest {
NodeResources maxResources = new NodeResources(10, 100, 100, 1);
ClusterResources min = new ClusterResources(5, 1, minResources);
ClusterResources max = new ClusterResources(5, 1, maxResources);
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(maxResources.withVcpu(maxResources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
@@ -705,35 +681,35 @@ public class AutoscalingTest {
tester.addLoadMeasurements(application1, cluster1.id(), 100, t -> t == 0 ? 20.0 : 10.0, t -> 10.0);
tester.assertResources("Query and write load is equal -> scale up somewhat",
5, 1, 7.3, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.addCpuMeasurements(0.4f, 1f, 100, application1);
tester.clock().advance(Duration.ofMinutes(-100 * 5));
tester.addLoadMeasurements(application1, cluster1.id(), 100, t -> t == 0 ? 80.0 : 40.0, t -> 10.0);
tester.assertResources("Query load is 4x write load -> scale up more",
5, 1, 9.5, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.addCpuMeasurements(0.3f, 1f, 100, application1);
tester.clock().advance(Duration.ofMinutes(-100 * 5));
tester.addLoadMeasurements(application1, cluster1.id(), 100, t -> t == 0 ? 20.0 : 10.0, t -> 100.0);
tester.assertResources("Write load is 10x query load -> scale down",
5, 1, 2.9, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.addCpuMeasurements(0.4f, 1f, 100, application1);
tester.clock().advance(Duration.ofMinutes(-100 * 5));
tester.addLoadMeasurements(application1, cluster1.id(), 100, t -> t == 0 ? 20.0 : 10.0, t-> 0.0);
tester.assertResources("Query only -> largest possible",
5, 1, 10.0, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
tester.addCpuMeasurements(0.4f, 1f, 100, application1);
tester.clock().advance(Duration.ofMinutes(-100 * 5));
tester.addLoadMeasurements(application1, cluster1.id(), 100, t -> 0.0, t -> 10.0);
tester.assertResources("Write only -> smallest possible",
5, 1, 2.1, 100, 100,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
@Test
@@ -741,7 +717,6 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(1, 4, 50, 1);
ClusterResources min = new ClusterResources( 2, 1, resources);
ClusterResources max = new ClusterResources(3, 1, resources);
- var capacity = Capacity.from(min, max);
AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
@@ -753,47 +728,7 @@ public class AutoscalingTest {
tester.assertResources("Advice to scale up since observed growth is much faster than scaling time",
3, 1, 1, 4, 50,
- tester.autoscale(application1, cluster1.id(), capacity).target());
- }
-
- @Test
- public void test_autoscaling_in_dev() {
- NodeResources resources = new NodeResources(1, 4, 50, 1);
- ClusterResources min = new ClusterResources( 1, 1, resources);
- ClusterResources max = new ClusterResources(3, 1, resources);
- Capacity capacity = Capacity.from(min, max, false, true);
-
- AutoscalingTester tester = new AutoscalingTester(Environment.dev, resources.withVcpu(resources.vcpu() * 2));
- ApplicationId application1 = tester.applicationId("application1");
- ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
-
- tester.deploy(application1, cluster1, capacity);
- tester.addQueryRateMeasurements(application1, cluster1.id(),
- 500, t -> 100.0);
- tester.addCpuMeasurements(1.0f, 1f, 10, application1);
- assertTrue("Not attempting to scale up because policies dictate we'll only get one node",
- tester.autoscale(application1, cluster1.id(), capacity).target().isEmpty());
- }
-
- /** Same setup as test_autoscaling_in_dev(), just with required = true */
- @Test
- public void test_autoscaling_in_dev_with_required_resources() {
- NodeResources resources = new NodeResources(1, 4, 50, 1);
- ClusterResources min = new ClusterResources( 1, 1, resources);
- ClusterResources max = new ClusterResources(3, 1, resources);
- Capacity capacity = Capacity.from(min, max, true, true);
-
- AutoscalingTester tester = new AutoscalingTester(Environment.dev, resources.withVcpu(resources.vcpu() * 2));
- ApplicationId application1 = tester.applicationId("application1");
- ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
-
- tester.deploy(application1, cluster1, capacity);
- tester.addQueryRateMeasurements(application1, cluster1.id(),
- 500, t -> 100.0);
- tester.addCpuMeasurements(1.0f, 1f, 10, application1);
- tester.assertResources("We scale up even in dev because resources are required",
- 3, 1, 1.0, 4, 50,
- tester.autoscale(application1, cluster1.id(), capacity).target());
+ tester.autoscale(application1, cluster1.id(), min, max).target());
}
/**
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
index 8d59181a027..c45b6caf14c 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
@@ -48,15 +48,11 @@ class AutoscalingTester {
/** Creates an autoscaling tester with a single host type ready */
public AutoscalingTester(NodeResources hostResources) {
- this(Environment.prod, hostResources);
+ this(hostResources, null);
}
- public AutoscalingTester(Environment environment, NodeResources hostResources) {
- this(environment, hostResources, null);
- }
-
- public AutoscalingTester(Environment environment, NodeResources hostResources, HostResourcesCalculator resourcesCalculator) {
- this(new Zone(environment, RegionName.from("us-east")), List.of(new Flavor("hostFlavor", hostResources)), resourcesCalculator);
+ public AutoscalingTester(NodeResources hostResources, HostResourcesCalculator resourcesCalculator) {
+ this(new Zone(Environment.prod, RegionName.from("us-east")), List.of(new Flavor("hostFlavor", hostResources)), resourcesCalculator);
provisioningTester.makeReadyNodes(20, "hostFlavor", NodeType.host, 8);
provisioningTester.activateTenantHosts();
}
@@ -255,7 +251,6 @@ class AutoscalingTester {
cluster.exclusive(),
cluster.minResources(),
cluster.maxResources(),
- cluster.required(),
cluster.suggestedResources(),
cluster.targetResources(),
List.of(), // Remove scaling events
@@ -300,9 +295,10 @@ class AutoscalingTester {
((MemoryMetricsDb)nodeMetricsDb()).clearClusterMetrics(application, cluster);
}
- public Autoscaler.Advice autoscale(ApplicationId applicationId, ClusterSpec.Id clusterId, Capacity capacity) {
+ public Autoscaler.Advice autoscale(ApplicationId applicationId, ClusterSpec.Id clusterId,
+ ClusterResources min, ClusterResources max) {
Application application = nodeRepository().applications().get(applicationId).orElse(Application.empty(applicationId))
- .withCluster(clusterId, false, capacity);
+ .withCluster(clusterId, false, min, max);
try (Mutex lock = nodeRepository().nodes().lock(applicationId)) {
nodeRepository().applications().put(application, lock);
}
@@ -313,7 +309,7 @@ class AutoscalingTester {
public Autoscaler.Advice suggest(ApplicationId applicationId, ClusterSpec.Id clusterId,
ClusterResources min, ClusterResources max) {
Application application = nodeRepository().applications().get(applicationId).orElse(Application.empty(applicationId))
- .withCluster(clusterId, false, Capacity.from(min, max));
+ .withCluster(clusterId, false, min, max);
try (Mutex lock = nodeRepository().nodes().lock(applicationId)) {
nodeRepository().applications().put(application, lock);
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModelTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModelTest.java
index bd7300ad6bf..0e37d953d2d 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModelTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModelTest.java
@@ -2,12 +2,12 @@
package com.yahoo.vespa.hosted.provision.autoscale;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.test.ManualClock;
import com.yahoo.vespa.hosted.provision.applications.Application;
+import com.yahoo.vespa.hosted.provision.applications.AutoscalingStatus;
import com.yahoo.vespa.hosted.provision.applications.Cluster;
import com.yahoo.vespa.hosted.provision.applications.Status;
import org.junit.Test;
@@ -15,6 +15,7 @@ import org.junit.Test;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.function.IntFunction;
import static org.junit.Assert.assertEquals;
@@ -72,9 +73,14 @@ public class ClusterModelTest {
}
private Cluster cluster(NodeResources resources) {
- return Cluster.create(ClusterSpec.Id.from("test"),
- false,
- Capacity.from(new ClusterResources(5, 1, resources)));
+ return new Cluster(ClusterSpec.Id.from("test"),
+ false,
+ new ClusterResources(5, 1, resources),
+ new ClusterResources(5, 1, resources),
+ Optional.empty(),
+ Optional.empty(),
+ List.of(),
+ AutoscalingStatus.empty());
}
/** Creates the given number of measurements, spaced 5 minutes between, using the given function */
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java
index e34f63d8062..7266da9ff46 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java
@@ -2,7 +2,6 @@
package com.yahoo.vespa.hosted.provision.persistence;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeResources;
@@ -34,7 +33,6 @@ public class ApplicationSerializerTest {
false,
new ClusterResources( 8, 4, new NodeResources(1, 2, 3, 4)),
new ClusterResources(12, 6, new NodeResources(3, 6, 21, 24)),
- true,
Optional.empty(),
Optional.empty(),
List.of(),
@@ -44,7 +42,6 @@ public class ApplicationSerializerTest {
true,
new ClusterResources( 8, 4, minResources),
new ClusterResources(14, 7, new NodeResources(3, 6, 21, 24)),
- false,
Optional.of(new Cluster.Suggestion(new ClusterResources(20, 10,
new NodeResources(0.5, 4, 14, 16)),
Instant.ofEpochMilli(1234L))),
@@ -75,7 +72,6 @@ public class ApplicationSerializerTest {
assertEquals(originalCluster.exclusive(), serializedCluster.exclusive());
assertEquals(originalCluster.minResources(), serializedCluster.minResources());
assertEquals(originalCluster.maxResources(), serializedCluster.maxResources());
- assertEquals(originalCluster.required(), serializedCluster.required());
assertEquals(originalCluster.suggestedResources(), serializedCluster.suggestedResources());
assertEquals(originalCluster.targetResources(), serializedCluster.targetResources());
assertEquals(originalCluster.scalingEvents(), serializedCluster.scalingEvents());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
index db165aae919..20546cc5bd9 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
@@ -1015,10 +1015,10 @@ public class ProvisioningTest {
allHosts.addAll(content1);
Function<Integer, Capacity> capacity = count -> Capacity.from(new ClusterResources(count, 1, NodeResources.unspecified()), required, true);
- int expectedContainer0Size = tester.decideSize(container0Size, capacity.apply(container0Size), containerCluster0, application);
- int expectedContainer1Size = tester.decideSize(container1Size, capacity.apply(container1Size), containerCluster1, application);
- int expectedContent0Size = tester.decideSize(content0Size, capacity.apply(content0Size), contentCluster0, application);
- int expectedContent1Size = tester.decideSize(content1Size, capacity.apply(content1Size), contentCluster1, application);
+ int expectedContainer0Size = tester.capacityPolicies().decideSize(container0Size, capacity.apply(container0Size), containerCluster0, application);
+ int expectedContainer1Size = tester.capacityPolicies().decideSize(container1Size, capacity.apply(container1Size), containerCluster1, application);
+ int expectedContent0Size = tester.capacityPolicies().decideSize(content0Size, capacity.apply(content0Size), contentCluster0, application);
+ int expectedContent1Size = tester.capacityPolicies().decideSize(content1Size, capacity.apply(content1Size), contentCluster1, application);
assertEquals("Hosts in each group cluster is disjunct and the total number of unretired nodes is correct",
expectedContainer0Size + expectedContainer1Size + expectedContent0Size + expectedContent1Size,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
index 6ca93671087..6d525762ecc 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
@@ -152,10 +152,6 @@ public class ProvisioningTester {
public NodeList getNodes(ApplicationId id, Node.State ... inState) { return nodeRepository.nodes().list(inState).owner(id); }
public InMemoryFlagSource flagSource() { return (InMemoryFlagSource) nodeRepository.flagSource(); }
- public int decideSize(int size, Capacity capacity, ClusterSpec cluster, ApplicationId application) {
- return capacityPolicies.decideSize(size, capacity.isRequired(), capacity.canFail(), application.instance().isTester(), cluster);
- }
-
public Node patchNode(Node node, UnaryOperator<Node> patcher) {
return patchNodes(List.of(node), patcher).get(0);
}