aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@yahooinc.com>2023-02-17 11:04:07 +0100
committerValerij Fredriksen <valerijf@yahooinc.com>2023-02-17 11:04:07 +0100
commitb27d11727a915108bf74906b588223db38cb8a2c (patch)
treec2a62696bbaabce95021ec1389d3c6abca4e8cde
parentf408843f6bead8fd4168611db97593fb96bbf4be (diff)
Require less vCPU for tester applications in prod
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java26
5 files changed, 28 insertions, 23 deletions
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 1406aaecb71..2ab0ac9d0d3 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
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.autoscale;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Flavor;
@@ -155,6 +156,7 @@ public class AllocatableClusterResources {
}
public static Optional<AllocatableClusterResources> from(ClusterResources wantedResources,
+ ApplicationId applicationId,
ClusterSpec clusterSpec,
Limits applicationLimits,
List<NodeResources> availableRealHostResources,
@@ -164,15 +166,15 @@ public class AllocatableClusterResources {
if (! exclusive) {
// 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, exclusive); // Ask for something legal
+ advertisedResources = systemLimits.enlargeToLegal(advertisedResources, applicationId, clusterSpec, exclusive); // Ask for something legal
advertisedResources = applicationLimits.cap(advertisedResources); // Overrides other conditions, even if it will then fail
var realResources = nodeRepository.resourcesCalculator().requestToReal(advertisedResources, exclusive); // What we'll really get
- if ( ! systemLimits.isWithinRealLimits(realResources, clusterSpec) && advertisedResources.storageType() == NodeResources.StorageType.any) {
+ if ( ! systemLimits.isWithinRealLimits(realResources, applicationId, clusterSpec) && advertisedResources.storageType() == NodeResources.StorageType.any) {
// Since local disk resreves some of the storage, try to constrain to remote disk
advertisedResources = advertisedResources.with(NodeResources.StorageType.remote);
realResources = nodeRepository.resourcesCalculator().requestToReal(advertisedResources, exclusive);
}
- if ( ! systemLimits.isWithinRealLimits(realResources, clusterSpec))
+ if ( ! systemLimits.isWithinRealLimits(realResources, applicationId, clusterSpec))
return Optional.empty();
if (anySatisfies(realResources, availableRealHostResources))
return Optional.of(new AllocatableClusterResources(wantedResources.with(realResources),
@@ -192,7 +194,7 @@ public class AllocatableClusterResources {
// Adjust where we don't need exact match to the flavor
if (flavor.resources().storageType() == NodeResources.StorageType.remote) {
- double diskGb = systemLimits.enlargeToLegal(cappedWantedResources, clusterSpec, exclusive).diskGb();
+ double diskGb = systemLimits.enlargeToLegal(cappedWantedResources, applicationId, clusterSpec, exclusive).diskGb();
advertisedResources = advertisedResources.withDiskGb(diskGb);
realResources = realResources.withDiskGb(diskGb);
}
@@ -202,7 +204,7 @@ public class AllocatableClusterResources {
}
if ( ! between(applicationLimits.min().nodeResources(), applicationLimits.max().nodeResources(), advertisedResources)) continue;
- if ( ! systemLimits.isWithinRealLimits(realResources, clusterSpec)) continue;
+ if ( ! systemLimits.isWithinRealLimits(realResources, applicationId, clusterSpec)) continue;
var candidate = new AllocatableClusterResources(wantedResources.with(realResources),
advertisedResources,
wantedResources,
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 e7278699ade..b3372aee356 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
@@ -1,8 +1,8 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.autoscale;
-import com.yahoo.config.provision.IntRange;
import com.yahoo.config.provision.ClusterResources;
+import com.yahoo.config.provision.IntRange;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.vespa.hosted.provision.NodeRepository;
@@ -58,7 +58,8 @@ public class AllocationOptimizer {
groups,
nodeResourcesWith(nodes, groups,
limits, targetLoad, current, clusterModel));
- var allocatableResources = AllocatableClusterResources.from(resources, current.clusterSpec(), limits,
+ var allocatableResources = AllocatableClusterResources.from(resources, clusterModel.application().id(),
+ current.clusterSpec(), limits,
availableRealHostResources, 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/provisioning/NodeAllocation.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
index a6d292b1a17..ab5cd577ea1 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
@@ -131,7 +131,7 @@ class NodeAllocation {
}
}
else if (! saturated() && hasCompatibleResources(candidate)) {
- if (! nodeResourceLimits.isWithinRealLimits(candidate, cluster)) {
+ if (! nodeResourceLimits.isWithinRealLimits(candidate, application, cluster)) {
++rejectedDueToInsufficientRealResources;
continue;
}
@@ -163,7 +163,7 @@ class NodeAllocation {
boolean alreadyRetired = candidate.allocation().map(a -> a.membership().retired()).orElse(false);
return alreadyRetired ? Retirement.alreadyRetired : Retirement.none;
}
- if ( ! nodeResourceLimits.isWithinRealLimits(candidate, cluster)) return Retirement.outsideRealLimits;
+ if ( ! nodeResourceLimits.isWithinRealLimits(candidate, application, cluster)) return Retirement.outsideRealLimits;
if (violatesParentHostPolicy(candidate)) return Retirement.violatesParentHostPolicy;
if ( ! hasCompatibleResources(candidate)) return Retirement.incompatibleResources;
if (candidate.wantToRetire()) return Retirement.hardRequest;
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 9f2ff373b28..526e6ed5a4e 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
@@ -88,8 +88,8 @@ public class NodeRepositoryProvisioner implements Provisioner {
if (cluster.group().isPresent()) throw new IllegalArgumentException("Node requests cannot specify a group");
- nodeResourceLimits.ensureWithinAdvertisedLimits("Min", requested.minResources().nodeResources(), cluster);
- nodeResourceLimits.ensureWithinAdvertisedLimits("Max", requested.maxResources().nodeResources(), cluster);
+ nodeResourceLimits.ensureWithinAdvertisedLimits("Min", requested.minResources().nodeResources(), application, cluster);
+ nodeResourceLimits.ensureWithinAdvertisedLimits("Max", requested.maxResources().nodeResources(), application, cluster);
int groups;
NodeResources resources;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java
index a944bf62534..1acb69113c1 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.provisioning;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.NodeResources;
@@ -25,11 +26,11 @@ public class NodeResourceLimits {
}
/** Validates the resources applications ask for (which are in "advertised" resource space) */
- public void ensureWithinAdvertisedLimits(String type, NodeResources requested, ClusterSpec cluster) {
+ public void ensureWithinAdvertisedLimits(String type, NodeResources requested, ApplicationId applicationId, ClusterSpec cluster) {
if (requested.isUnspecified()) return;
- if (requested.vcpu() < minAdvertisedVcpu(cluster))
- illegal(type, "vcpu", "", cluster, requested.vcpu(), minAdvertisedVcpu(cluster));
+ if (requested.vcpu() < minAdvertisedVcpu(applicationId, cluster))
+ illegal(type, "vcpu", "", cluster, requested.vcpu(), minAdvertisedVcpu(applicationId, cluster));
if (requested.memoryGb() < minAdvertisedMemoryGb(cluster))
illegal(type, "memoryGb", "Gb", cluster, requested.memoryGb(), minAdvertisedMemoryGb(cluster));
if (requested.diskGb() < minAdvertisedDiskGb(requested, cluster.isExclusive()))
@@ -37,33 +38,34 @@ public class NodeResourceLimits {
}
/** Returns whether the real resources we'll end up with on a given tenant node are within limits */
- public boolean isWithinRealLimits(NodeCandidate candidateNode, ClusterSpec cluster) {
+ public boolean isWithinRealLimits(NodeCandidate candidateNode, ApplicationId applicationId, ClusterSpec cluster) {
if (candidateNode.type() != NodeType.tenant) return true; // Resource limits only apply to tenant nodes
return isWithinRealLimits(nodeRepository.resourcesCalculator().realResourcesOf(candidateNode, nodeRepository),
- cluster);
+ applicationId, cluster);
}
/** Returns whether the real resources we'll end up with on a given tenant node are within limits */
- public boolean isWithinRealLimits(NodeResources realResources, ClusterSpec cluster) {
+ public boolean isWithinRealLimits(NodeResources realResources, ApplicationId applicationId, ClusterSpec cluster) {
if (realResources.isUnspecified()) return true;
- if (realResources.vcpu() < minRealVcpu(cluster)) return false;
+ if (realResources.vcpu() < minRealVcpu(applicationId, cluster)) return false;
if (realResources.memoryGb() < minRealMemoryGb(cluster)) return false;
if (realResources.diskGb() < minRealDiskGb()) return false;
return true;
}
- public NodeResources enlargeToLegal(NodeResources requested, ClusterSpec cluster, boolean exclusive) {
+ public NodeResources enlargeToLegal(NodeResources requested, ApplicationId applicationId, ClusterSpec cluster, boolean exclusive) {
if (requested.isUnspecified()) return requested;
- return requested.withVcpu(Math.max(minAdvertisedVcpu(cluster), requested.vcpu()))
+ return requested.withVcpu(Math.max(minAdvertisedVcpu(applicationId, cluster), requested.vcpu()))
.withMemoryGb(Math.max(minAdvertisedMemoryGb(cluster), requested.memoryGb()))
.withDiskGb(Math.max(minAdvertisedDiskGb(requested, exclusive), requested.diskGb()));
}
- private double minAdvertisedVcpu(ClusterSpec cluster) {
+ private double minAdvertisedVcpu(ApplicationId applicationId, ClusterSpec cluster) {
if (cluster.type() == ClusterSpec.Type.admin) return 0.1;
- if (zone().environment().isProduction() && ! zone().system().isCd() && nodeRepository.exclusiveAllocation(cluster)) return 2;
+ if (zone().environment().isProduction() && ! zone().system().isCd() &&
+ nodeRepository.exclusiveAllocation(cluster) && ! applicationId.instance().isTester()) return 2;
if (zone().environment().isProduction() && cluster.type().isContent()) return 1.0;
if (zone().environment() == Environment.dev && ! nodeRepository.exclusiveAllocation(cluster)) return 0.1;
return 0.5;
@@ -86,7 +88,7 @@ public class NodeResourceLimits {
return 4;
}
- private double minRealVcpu(ClusterSpec cluster) { return minAdvertisedVcpu(cluster); }
+ private double minRealVcpu(ApplicationId applicationId, ClusterSpec cluster) { return minAdvertisedVcpu(applicationId, cluster); }
private double minRealMemoryGb(ClusterSpec cluster) {
return minAdvertisedMemoryGb(cluster) - 1.7;