aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository/src/main/java
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@vespa.ai>2024-04-21 17:00:07 +0200
committerJon Bratseth <bratseth@vespa.ai>2024-04-21 17:00:07 +0200
commit93762349e5eef8e8ff26d5a557d4d1eb758720d2 (patch)
tree47acb4a7ecc8b939818718197aaa9ed2f94bf241 /node-repository/src/main/java
parentad3f46af34fda17189e2cafd650c70b72a5804b4 (diff)
Retire incrementally
Diffstat (limited to 'node-repository/src/main/java')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java19
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java12
3 files changed, 16 insertions, 27 deletions
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 8c52f389daf..b149a9af2c2 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
@@ -179,6 +179,13 @@ class NodeAllocation {
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;
+
+ var group = candidate.allocation().get().membership().cluster().group();
+ if (cluster.isStateful() && group.isPresent() && requested.count().isPresent()) {
+ long nodesInGroup = nodes.values().stream().filter(n -> groupOf(n).equals(group) && ! isRetired(n)).count();
+ if (nodesInGroup >= requested.groupSize())
+ return Retirement.groupSurplus;
+ }
return Retirement.none;
}
@@ -290,6 +297,10 @@ class NodeAllocation {
return candidate.allocation().flatMap(a -> a.membership().cluster().group());
}
+ private boolean isRetired(NodeCandidate candidate) {
+ return candidate.allocation().map(a -> a.membership().retired()).orElse(false);
+ }
+
private Node resize(Node node) {
NodeResources hostResources = allNodes.parentOf(node).get().flavor().resources();
return node.with(new Flavor(requested.resources().get()
@@ -463,6 +474,7 @@ class NodeAllocation {
violatesHostFlavor("node violates host flavor"),
violatesHostFlavorGeneration("node violates host flavor generation"),
violatesSpares("node is assigned to a host we want to use as a spare"),
+ groupSurplus("group has enough nodes"),
none("");
private final String description;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java
index c599e7fd1f0..cb50f6dff2b 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java
@@ -80,11 +80,9 @@ public interface NodeSpec {
return false;
}
- NodeSpec withExtra(int nodeCount);
-
static NodeSpec from(int nodeCount, int groupCount, NodeResources resources, boolean exclusive, boolean canFail,
CloudAccount cloudAccount, Duration hostTTL) {
- return new CountNodeSpec(nodeCount, groupCount, resources, 0, exclusive, canFail, canFail, cloudAccount, hostTTL);
+ return new CountNodeSpec(nodeCount, groupCount, resources, exclusive, canFail, canFail, cloudAccount, hostTTL);
}
static NodeSpec from(NodeType type, CloudAccount cloudAccount) {
@@ -97,20 +95,17 @@ public interface NodeSpec {
private final int count;
private final int groups;
private final NodeResources requestedNodeResources;
- private final int extraNodesNeeded;
private final boolean exclusive;
private final boolean canFail;
private final boolean considerRetiring;
private final CloudAccount cloudAccount;
private final Duration hostTTL;
- private CountNodeSpec(int count, int groups, NodeResources resources, int extraNodesNeeded,
- boolean exclusive, boolean canFail,
+ private CountNodeSpec(int count, int groups, NodeResources resources, boolean exclusive, boolean canFail,
boolean considerRetiring, CloudAccount cloudAccount, Duration hostTTL) {
this.count = count;
this.groups = groups;
this.requestedNodeResources = Objects.requireNonNull(resources, "Resources must be specified");
- this.extraNodesNeeded = extraNodesNeeded; // ... due to reducing group size
this.exclusive = exclusive;
this.canFail = canFail;
this.considerRetiring = considerRetiring;
@@ -153,11 +148,11 @@ public interface NodeSpec {
@Override
public int fulfilledDeficitCount(int count) {
- return Math.max(this.count + extraNodesNeeded - count, 0);
+ return Math.max(this.count - count, 0);
}
public NodeSpec withoutRetiring() {
- return new CountNodeSpec(count, groups, requestedNodeResources, extraNodesNeeded, exclusive, canFail, false, cloudAccount, hostTTL);
+ return new CountNodeSpec(count, groups, requestedNodeResources, exclusive, canFail, false, cloudAccount, hostTTL);
}
@Override
@@ -191,10 +186,6 @@ public interface NodeSpec {
@Override
public Duration hostTTL() { return hostTTL; }
- public NodeSpec withExtra(int nodeCount) {
- return new CountNodeSpec(count, groups, requestedNodeResources, nodeCount, exclusive, canFail, considerRetiring, cloudAccount, hostTTL);
- }
-
@Override
public String toString() {
return "request for " + count + " nodes" +
@@ -268,8 +259,6 @@ public interface NodeSpec {
return cloudAccount;
}
- public NodeSpec withExtra(int nodeCount) { return this; }
-
@Override
public String toString() { return "request for nodes of type '" + type + "'"; }
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 ea8e7d7db6e..0206c3a4a26 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
@@ -188,7 +188,6 @@ public class Preparer {
private NodeAllocation prepareAllocation(ApplicationId application, ClusterSpec cluster, NodeSpec requested,
Supplier<Integer> nextIndex, LockedNodeList allNodes) {
validateAccount(requested.cloudAccount(), application, allNodes);
- requested = requested.withExtra(extraNodesNeeded(application, cluster, requested, allNodes));
NodeAllocation allocation = new NodeAllocation(allNodes, application, cluster, requested, nextIndex, nodeRepository);
IP.Allocation.Context allocationContext = IP.Allocation.Context.from(nodeRepository.zone().cloud().name(),
requested.cloudAccount().isExclave(nodeRepository.zone()),
@@ -214,17 +213,6 @@ public class Preparer {
return allocation;
}
- private int extraNodesNeeded(ApplicationId application, ClusterSpec cluster, NodeSpec requested, LockedNodeList allNodes) {
- if ( ! cluster.isStateful()) return 0;
- if ( ! requested.count().isPresent()) return 0;
- int currentGroupSize = allNodes.owner(application).cluster(cluster.id()).state(Node.State.active).not().retired().group(0).size();
- long currentGroupCount = allNodes.owner(application).cluster(cluster.id()).state(Node.State.active).not().retired().stream()
- .map(node -> node.allocation().get().membership().cluster().group().get()).distinct().count();
- int newGroupSize = requested.groupSize();
- int surplusPerGroup = Math.max(0, currentGroupSize - newGroupSize);
- return surplusPerGroup * (int) currentGroupCount;
- }
-
private void validateAccount(CloudAccount requestedAccount, ApplicationId application, LockedNodeList allNodes) {
CloudAccount effectiveAccount = requestedAccount.isUnspecified() ? nodeRepository.zone().cloud().account() : requestedAccount;
List<Node> nodesInOtherAccount = allNodes.owner(application).nodeType(NodeType.tenant).stream()