diff options
author | Jon Bratseth <bratseth@vespa.ai> | 2023-08-15 12:43:18 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@vespa.ai> | 2023-08-15 12:43:18 +0200 |
commit | 69e37f2811297b7f6fbaa6ee1995b8880ba448fc (patch) | |
tree | 54829875cc6533555c38a0d641267bbbe9715866 | |
parent | ee2cde5a803ee3f553b7495eb642b455d19ca64f (diff) |
Consider switching cost when choosing host flavor
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; |