summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@vespa.ai>2023-08-15 12:43:18 +0200
committerJon Bratseth <bratseth@vespa.ai>2023-08-15 12:43:18 +0200
commit69e37f2811297b7f6fbaa6ee1995b8880ba448fc (patch)
tree54829875cc6533555c38a0d641267bbbe9715866
parentee2cde5a803ee3f553b7495eb642b455d19ca64f (diff)
Consider switching cost when choosing host flavor
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java22
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java18
2 files changed, 19 insertions, 21 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 0f100593e38..a4e1a62f5b9 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
@@ -10,6 +10,7 @@ import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
import com.yahoo.vespa.hosted.provision.NodeRepository;
+import java.time.Duration;
import java.util.List;
import java.util.Optional;
@@ -129,11 +130,18 @@ public class AllocatableClusterResources {
return (vcpuFulfilment + memoryGbFulfilment + diskGbFulfilment) / 3;
}
- public boolean preferableTo(AllocatableClusterResources other) {
- if (this.fulfilment < 1 || other.fulfilment < 1) // always fulfil as much as possible
- return this.fulfilment > other.fulfilment;
+ public boolean preferableTo(AllocatableClusterResources other,
+ AllocatableClusterResources current, ClusterModel clusterModel) {
+ if (other.fulfilment() < 1 || this.fulfilment() < 1) // always fulfil as much as possible
+ return this.fulfilment() > other.fulfilment();
- return this.cost() < other.cost(); // otherwise, prefer lower cost
+ return this.cost() * toHours(clusterModel.allocationDuration()) + this.costChangingFrom(current, clusterModel)
+ <
+ other.cost() * toHours(clusterModel.allocationDuration()) + other.costChangingFrom(current, clusterModel);
+ }
+
+ private double toHours(Duration duration) {
+ return duration.toMillis() / 3600000.0;
}
/** The estimated cost of changing from the given current resources to this. */
@@ -165,6 +173,8 @@ public class AllocatableClusterResources {
ClusterSpec clusterSpec,
Limits applicationLimits,
List<NodeResources> availableRealHostResources,
+ AllocatableClusterResources current,
+ ClusterModel clusterModel,
NodeRepository nodeRepository) {
var systemLimits = nodeRepository.nodeResourceLimits();
boolean exclusive = nodeRepository.exclusiveAllocation(clusterSpec);
@@ -228,12 +238,12 @@ public class AllocatableClusterResources {
clusterSpec);
if ( ! systemLimits.isWithinAdvertisedDiskLimits(advertisedResources, clusterSpec)) { // TODO: Remove when disk limit is enforced
- if (bestDisregardingDiskLimit.isEmpty() || candidate.preferableTo(bestDisregardingDiskLimit.get())) {
+ if (bestDisregardingDiskLimit.isEmpty() || candidate.preferableTo(bestDisregardingDiskLimit.get(), current, clusterModel)) {
bestDisregardingDiskLimit = Optional.of(candidate);
}
continue;
}
- if (best.isEmpty() || candidate.preferableTo(best.get())) {
+ if (best.isEmpty() || candidate.preferableTo(best.get(), current, clusterModel)) {
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 2511f17ee1a..deff92628e7 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,29 +65,17 @@ public class AllocationOptimizer {
current.clusterSpec(),
limits,
availableRealHostResources,
+ current,
+ clusterModel,
nodeRepository);
if (allocatableResources.isEmpty()) continue;
- if (bestAllocation.isEmpty() || preferableTo(bestAllocation.get(), allocatableResources.get(), current, clusterModel))
+ if (bestAllocation.isEmpty() || allocatableResources.get().preferableTo(bestAllocation.get(), current, clusterModel))
bestAllocation = allocatableResources;
}
}
return bestAllocation;
}
- private boolean preferableTo(AllocatableClusterResources best, AllocatableClusterResources considered,
- AllocatableClusterResources current, ClusterModel clusterModel) {
- if (best.fulfilment() < 1 || considered.fulfilment() < 1) // always fulfil as much as possible
- return considered.fulfilment() > best.fulfilment();
-
- return considered.cost() * toHours(clusterModel.allocationDuration()) + considered.costChangingFrom(current, clusterModel)
- <
- best.cost() * toHours(clusterModel.allocationDuration()) + best.costChangingFrom(current, clusterModel);
- }
-
- private double toHours(Duration duration) {
- return duration.toMillis() / 3600000.0;
- }
-
/** Returns the max resources of a host one node may allocate. */
private NodeResources maxResourcesOf(NodeResources hostResources, ClusterModel clusterModel) {
if (nodeRepository.exclusiveAllocation(clusterModel.clusterSpec())) return hostResources;