diff options
author | Jon Bratseth <bratseth@gmail.com> | 2021-06-03 11:49:37 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2021-06-03 11:49:37 +0200 |
commit | 69e624148d70bbedb67f1faaca91ae66c77bdd68 (patch) | |
tree | a50015cb7f2c0974be4fffd74c00f891cde31ca4 | |
parent | 5bf38bbdda250c5fdac68a1f8d989fb303702715 (diff) |
Use default node resources when none are specified
6 files changed, 54 insertions, 10 deletions
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 0a1c6c5df6b..22ff4bdb0f4 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 @@ -7,6 +7,7 @@ import com.yahoo.config.provision.NodeResources; import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.applications.Cluster; +import com.yahoo.vespa.hosted.provision.provisioning.CapacityPolicies; import java.util.Optional; @@ -48,7 +49,7 @@ public class AllocationOptimizer { limits = Limits.of(new ClusterResources(minimumNodes, 1, NodeResources.unspecified()), new ClusterResources(maximumNodes, maximumNodes, NodeResources.unspecified())); else - limits = atLeast(minimumNodes, limits); + limits = atLeast(minimumNodes, limits).fullySpecified(current.clusterSpec().type(), nodeRepository); Optional<AllocatableClusterResources> bestAllocation = Optional.empty(); NodeList hosts = nodeRepository.nodes().list().hosts(); for (int groups = limits.min().groups(); groups <= limits.max().groups(); groups++) { 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 19cc9f5714f..bbac3bf93da 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,10 +32,8 @@ 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 MetricsDb metricsDb; private final Clock clock; private final Duration scalingDuration; private final ClusterTimeseries clusterTimeseries; @@ -52,9 +50,7 @@ public class ClusterModel { MetricsDb metricsDb, Clock clock) { this.application = application; - this.cluster = cluster; this.nodes = clusterNodes; - this.metricsDb = metricsDb; this.clock = clock; this.scalingDuration = computeScalingDuration(cluster, clusterSpec); this.clusterTimeseries = metricsDb.getClusterTimeseries(application.id(), cluster.id()); @@ -69,9 +65,7 @@ public class ClusterModel { ClusterTimeseries clusterTimeseries, ClusterNodesTimeseries nodeTimeseries) { this.application = application; - this.cluster = cluster; this.nodes = null; - this.metricsDb = null; this.clock = clock; this.scalingDuration = scalingDuration; diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java index 80ad81f6cdf..3dcaec63448 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java @@ -3,8 +3,11 @@ package com.yahoo.vespa.hosted.provision.autoscale; 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.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.applications.Cluster; +import com.yahoo.vespa.hosted.provision.provisioning.CapacityPolicies; import java.util.Objects; @@ -56,6 +59,16 @@ public class Limits { return resources; } + public Limits fullySpecified(ClusterSpec.Type type, NodeRepository nodeRepository) { + if (this.isEmpty()) return this; + CapacityPolicies capacityPolicies = new CapacityPolicies(nodeRepository); + var specifiedMin = min.with(min.nodeResources().isUnspecified() ? + capacityPolicies.defaultNodeResources(type) : min.nodeResources()); + var specifiedMax = max.with(max.nodeResources().isUnspecified() ? + capacityPolicies.defaultNodeResources(type) : max.nodeResources()); + return new Limits(specifiedMin, specifiedMax); + } + private double between(double min, double max, double value) { value = Math.max(min, value); value = Math.min(max, value); 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 711fe39d056..abd910485ac 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 @@ -60,7 +60,7 @@ public class CapacityPolicies { return target; } - private NodeResources defaultNodeResources(ClusterSpec.Type clusterType) { + public NodeResources defaultNodeResources(ClusterSpec.Type clusterType) { if (clusterType == ClusterSpec.Type.admin) { if (zone.system() == SystemName.dev) { // Use small logserver in dev system 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 98bfa2170a5..41a399c5e2f 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 @@ -15,6 +15,7 @@ import com.yahoo.config.provision.SystemName; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.Nodelike; +import com.yahoo.vespa.hosted.provision.provisioning.CapacityPolicies; import com.yahoo.vespa.hosted.provision.provisioning.HostResourcesCalculator; import org.junit.Test; @@ -219,6 +220,32 @@ public class AutoscalingTest { } @Test + public void autoscaling_with_unspecified_resources_use_defaults() { + NodeResources hostResources = new NodeResources(6, 100, 100, 1); + ClusterResources min = new ClusterResources( 2, 1, NodeResources.unspecified()); + ClusterResources max = new ClusterResources( 6, 1, NodeResources.unspecified()); + AutoscalingTester tester = new AutoscalingTester(hostResources); + + ApplicationId application1 = tester.applicationId("application1"); + ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1"); + + NodeResources defaultResources = + new CapacityPolicies(tester.nodeRepository()).defaultNodeResources(cluster1.type()); + + // deploy + tester.deploy(application1, cluster1, Capacity.from(min, max)); + tester.assertResources("Min number of nodes and default resources", + 2, 1, defaultResources, + Optional.of(tester.nodeRepository().nodes().list().owner(application1).toResources())); + tester.addMeasurements(0.25f, 0.95f, 0.95f, 0, 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 up to limit since resource usage is too high", + 4, 1, defaultResources, + tester.autoscale(application1, cluster1.id(), min, max).target()); + } + + @Test public void autoscaling_respects_group_limit() { NodeResources hostResources = new NodeResources(30.0, 100, 100, 1); ClusterResources min = new ClusterResources( 2, 2, new NodeResources(1, 1, 1, 1)); 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 5fe6023e5af..f96679b7195 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 @@ -267,7 +267,7 @@ class AutoscalingTester { } public Autoscaler.Advice autoscale(ApplicationId applicationId, ClusterSpec.Id clusterId, - ClusterResources min, ClusterResources max) { + ClusterResources min, ClusterResources max) { Application application = nodeRepository().applications().get(applicationId).orElse(Application.empty(applicationId)) .withCluster(clusterId, false, min, max); try (Mutex lock = nodeRepository().nodes().lock(applicationId)) { @@ -278,7 +278,7 @@ class AutoscalingTester { } public Autoscaler.Advice suggest(ApplicationId applicationId, ClusterSpec.Id clusterId, - ClusterResources min, ClusterResources max) { + ClusterResources min, ClusterResources max) { Application application = nodeRepository().applications().get(applicationId).orElse(Application.empty(applicationId)) .withCluster(clusterId, false, min, max); try (Mutex lock = nodeRepository().nodes().lock(applicationId)) { @@ -290,6 +290,15 @@ class AutoscalingTester { public ClusterResources assertResources(String message, int nodeCount, int groupCount, + NodeResources expectedResources, + Optional<ClusterResources> resources) { + return assertResources(message, nodeCount, groupCount, + expectedResources.vcpu(), expectedResources.memoryGb(), expectedResources.diskGb(), + resources); + } + + public ClusterResources assertResources(String message, + int nodeCount, int groupCount, double approxCpu, double approxMemory, double approxDisk, Optional<ClusterResources> resources) { double delta = 0.0000000001; |