diff options
author | Valerij Fredriksen <freva@users.noreply.github.com> | 2023-10-24 16:57:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-24 16:57:31 +0200 |
commit | bc3b03f9189b2b575f1c3b1bfe0c2a79bab555ce (patch) | |
tree | 0f161b47d4a7059ffe95adb227e4348ad0509afd /node-repository | |
parent | 7f6f44d95e95706c0a31937c5dc89c20d09051ca (diff) | |
parent | df2aed8b80016984617bc4effe530d842b78a523 (diff) |
Merge pull request #29084 from vespa-engine/hakonhall/node-must-fit-host-only-if-allocation-is-exclusive
Node must fit host (only) if allocation is exclusive
Diffstat (limited to 'node-repository')
4 files changed, 30 insertions, 15 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java index a5135ca0e1f..7155a49ef58 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java @@ -278,20 +278,21 @@ public class HostCapacityMaintainer extends NodeRepositoryMaintainer { // We'll allocate each ClusterCapacity as a unique cluster in a dummy application ApplicationId applicationId = ApplicationId.defaultId(); - ClusterSpec clusterSpec = asSpec(Optional.ofNullable(clusterCapacity.clusterType()), clusterIndex); + ClusterSpec cluster = asSpec(Optional.ofNullable(clusterCapacity.clusterType()), clusterIndex); NodeSpec nodeSpec = NodeSpec.from(clusterCapacity.count(), 1, nodeResources, false, true, nodeRepository().zone().cloud().account(), Duration.ZERO); var allocationContext = IP.Allocation.Context.from(nodeRepository().zone().cloud().name(), nodeSpec.cloudAccount().isExclave(nodeRepository().zone()), nodeRepository().nameResolver()); - NodePrioritizer prioritizer = new NodePrioritizer(allNodes, applicationId, clusterSpec, nodeSpec, - true, allocationContext, nodeRepository().nodes(), nodeRepository().resourcesCalculator(), - nodeRepository().spareCount()); + NodePrioritizer prioritizer = new NodePrioritizer(allNodes, applicationId, cluster, nodeSpec, + true, false, allocationContext, nodeRepository().nodes(), + nodeRepository().resourcesCalculator(), nodeRepository().spareCount(), + nodeRepository().exclusiveAllocation(cluster), makeExclusive); List<NodeCandidate> nodeCandidates = prioritizer.collect() .stream() - .filter(node -> node.violatesExclusivity(clusterSpec, + .filter(node -> node.violatesExclusivity(cluster, applicationId, - nodeRepository().exclusiveAllocation(clusterSpec), + nodeRepository().exclusiveAllocation(cluster), false, nodeRepository().zone().cloud().allowHostSharing(), allNodes, @@ -304,7 +305,7 @@ public class HostCapacityMaintainer extends NodeRepositoryMaintainer { .limit(clusterCapacity.count()) .map(candidate -> candidate.toNode() .allocate(applicationId, - ClusterMembership.from(clusterSpec, index.next()), + ClusterMembership.from(cluster, index.next()), nodeResources, nodeRepository().clock().instant())) .toList(); 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 0cb1eaa574c..e1be5b48e2d 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 @@ -141,7 +141,7 @@ class NodeAllocation { ++rejectedDueToClashingParentHost; continue; } - switch (violatesExclusivity(candidate, makeExclusive)) { + switch (violatesExclusivity(candidate)) { case PARENT_HOST_NOT_EXCLUSIVE -> candidate = candidate.withExclusiveParent(true); case NONE -> {} case YES -> { @@ -175,7 +175,7 @@ class NodeAllocation { if (candidate.parent.map(node -> node.status().wantToUpgradeFlavor()).orElse(false)) return Retirement.violatesHostFlavorGeneration; if (candidate.wantToRetire()) return Retirement.hardRequest; if (candidate.preferToRetire() && candidate.replaceableBy(candidates)) return Retirement.softRequest; - if (violatesExclusivity(candidate, makeExclusive) != NodeCandidate.ExclusivityViolation.NONE) return Retirement.violatesExclusivity; + if (violatesExclusivity(candidate) != NodeCandidate.ExclusivityViolation.NONE) return Retirement.violatesExclusivity; if (requiredHostFlavor.isPresent() && ! candidate.parent.map(node -> node.flavor().name()).equals(requiredHostFlavor)) return Retirement.violatesHostFlavor; if (candidate.violatesSpares) return Retirement.violatesSpares; return Retirement.none; @@ -196,7 +196,7 @@ class NodeAllocation { return nodes.values().stream().anyMatch(acceptedNode -> acceptedNode.parentHostname().equals(candidate.parentHostname())); } - private NodeCandidate.ExclusivityViolation violatesExclusivity(NodeCandidate candidate, boolean makeExclusive) { + private NodeCandidate.ExclusivityViolation violatesExclusivity(NodeCandidate candidate) { return candidate.violatesExclusivity(cluster, application, nodeRepository.exclusiveAllocation(cluster), nodeRepository.exclusiveProvisioning(cluster), diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java index d0b13bb7f6c..b92d6fb6d18 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java @@ -9,7 +9,6 @@ import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.node.IP; import com.yahoo.vespa.hosted.provision.node.Nodes; -import com.yahoo.vespa.hosted.provision.persistence.NameResolver; import java.util.ArrayList; import java.util.Collections; @@ -40,14 +39,17 @@ public class NodePrioritizer { private final IP.Allocation.Context ipAllocationContext; private final Nodes nodes; private final boolean dynamicProvisioning; + private final boolean allowHostSharing; + private final boolean exclusiveAllocation; + private final boolean makeExclusive; private final boolean canAllocateToSpareHosts; private final boolean topologyChange; private final int currentClusterSize; private final Set<Node> spareHosts; public NodePrioritizer(LockedNodeList allNodes, ApplicationId application, ClusterSpec clusterSpec, NodeSpec nodeSpec, - boolean dynamicProvisioning, IP.Allocation.Context ipAllocationContext, Nodes nodes, - HostResourcesCalculator hostResourcesCalculator, int spareCount) { + boolean dynamicProvisioning, boolean allowHostSharing, IP.Allocation.Context ipAllocationContext, Nodes nodes, + HostResourcesCalculator hostResourcesCalculator, int spareCount, boolean exclusiveAllocation, boolean makeExclusive) { this.allNodes = allNodes; this.calculator = hostResourcesCalculator; this.capacity = new HostCapacity(this.allNodes, hostResourcesCalculator); @@ -55,6 +57,9 @@ public class NodePrioritizer { this.clusterSpec = clusterSpec; this.application = application; this.dynamicProvisioning = dynamicProvisioning; + this.allowHostSharing = allowHostSharing; + this.exclusiveAllocation = exclusiveAllocation; + this.makeExclusive = makeExclusive; this.spareHosts = dynamicProvisioning ? capacity.findSpareHostsInDynamicallyProvisionedZones(this.allNodes.asList()) : capacity.findSpareHosts(this.allNodes.asList(), spareCount); @@ -122,7 +127,13 @@ public class NodePrioritizer { if (nodes.suspended(host)) continue; // Hosts that are suspended may be down for some time, e.g. for OS upgrade if (host.reservedTo().isPresent() && !host.reservedTo().get().equals(application.tenant())) continue; if (host.reservedTo().isPresent() && application.instance().isTester()) continue; - if (host.exclusiveToApplicationId().isPresent() && ! fitsPerfectly(host)) continue; + if (makeExclusive) { + if ( ! allowHostSharing && exclusiveAllocation && ! fitsPerfectly(host)) continue; + } else { + if (host.exclusiveToApplicationId().isPresent() && ! fitsPerfectly(host)) continue; + } + if ( ! host.provisionedForApplicationId().map(application::equals).orElse(true)) continue; + if ( ! host.exclusiveToApplicationId().map(application::equals).orElse(true)) continue; if ( ! host.exclusiveToClusterType().map(clusterSpec.type()::equals).orElse(true)) continue; if (spareHosts.contains(host) && !canAllocateToSpareHosts) continue; if ( ! capacity.hasCapacity(host, requested.resources().get())) continue; diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java index 9cbd3765cf8..9f5775ee8c3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java @@ -189,10 +189,13 @@ public class Preparer { cluster, requested, nodeRepository.zone().cloud().dynamicProvisioning(), + nodeRepository.zone().cloud().allowHostSharing(), allocationContext, nodeRepository.nodes(), nodeRepository.resourcesCalculator(), - nodeRepository.spareCount()); + nodeRepository.spareCount(), + nodeRepository.exclusiveAllocation(cluster), + makeExclusive); allocation.offer(prioritizer.collect()); return allocation; } |