From 6cea39acbccede2b3f71bd4de768e2b3f5588f81 Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Thu, 6 May 2021 18:27:38 +0200 Subject: Only include non-retired nodes in redundancy computation Usually redundancy is down-adjusted to match the nodes per group, but not if the node count requested is high enough but downscaled by capacity policies. The redundancy is also adjusted down if there are not enough nodes in the actual allocation, which normally handles this case, but not if there are retired nodes. That is fixed in this PR by not counting retired nodes when making that adjustment. --- .../model/provision/InMemoryProvisioner.java | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'config-model/src/main/java/com/yahoo/config/model/provision') diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java index 188504edd18..e41e7309986 100644 --- a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java +++ b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java @@ -63,6 +63,8 @@ public class InMemoryProvisioner implements HostProvisioner { private final boolean useMaxResources; + private final boolean alwaysReturnOneNode; + private Provisioned provisioned = new Provisioned(); /** Creates this with a number of nodes with resources 1, 3, 9, 1 */ @@ -72,37 +74,39 @@ public class InMemoryProvisioner implements HostProvisioner { /** Creates this with a number of nodes with given resources */ public InMemoryProvisioner(int nodeCount, NodeResources resources, boolean sharedHosts) { - this(Map.of(resources, createHostInstances(nodeCount)), true, false, sharedHosts, 0); + this(Map.of(resources, createHostInstances(nodeCount)), true, false, false, sharedHosts, 0); } /** Creates this with a set of host names of the flavor 'default' */ public InMemoryProvisioner(boolean failOnOutOfCapacity, boolean sharedHosts, String... hosts) { - this(Map.of(defaultResources, toHostInstances(hosts)), failOnOutOfCapacity, false, sharedHosts, 0); + this(Map.of(defaultResources, toHostInstances(hosts)), failOnOutOfCapacity, false, false, sharedHosts, 0); } /** Creates this with a set of host names of the flavor 'default' */ public InMemoryProvisioner(boolean failOnOutOfCapacity, boolean sharedHosts, List hosts) { - this(Map.of(defaultResources, toHostInstances(hosts.toArray(new String[0]))), failOnOutOfCapacity, false, sharedHosts, 0); + this(Map.of(defaultResources, toHostInstances(hosts.toArray(new String[0]))), failOnOutOfCapacity, false, false, sharedHosts, 0); } /** Creates this with a set of hosts of the flavor 'default' */ public InMemoryProvisioner(Hosts hosts, boolean failOnOutOfCapacity, boolean sharedHosts, String ... retiredHostNames) { - this(Map.of(defaultResources, hosts.asCollection()), failOnOutOfCapacity, false, sharedHosts, 0, retiredHostNames); + this(Map.of(defaultResources, hosts.asCollection()), failOnOutOfCapacity, false, false, sharedHosts, 0, retiredHostNames); } /** Creates this with a set of hosts of the flavor 'default' */ public InMemoryProvisioner(Hosts hosts, boolean failOnOutOfCapacity, boolean sharedHosts, int startIndexForClusters, String ... retiredHostNames) { - this(Map.of(defaultResources, hosts.asCollection()), failOnOutOfCapacity, false, sharedHosts, startIndexForClusters, retiredHostNames); + this(Map.of(defaultResources, hosts.asCollection()), failOnOutOfCapacity, false, false, sharedHosts, startIndexForClusters, retiredHostNames); } public InMemoryProvisioner(Map> hosts, boolean failOnOutOfCapacity, boolean useMaxResources, + boolean alwaysReturnOneNode, boolean sharedHosts, int startIndexForClusters, String ... retiredHostNames) { this.failOnOutOfCapacity = failOnOutOfCapacity; this.useMaxResources = useMaxResources; + this.alwaysReturnOneNode = alwaysReturnOneNode; for (Map.Entry> hostsWithResources : hosts.entrySet()) for (Host host : hostsWithResources.getValue()) freeNodes.put(hostsWithResources.getKey(), host); @@ -142,16 +146,20 @@ public class InMemoryProvisioner implements HostProvisioner { public List prepare(ClusterSpec cluster, ClusterResources requested, boolean required, boolean canFail) { if (cluster.group().isPresent() && requested.groups() > 1) throw new IllegalArgumentException("Cannot both be specifying a group and ask for groups to be created"); - int capacity = failOnOutOfCapacity || required + + int nodes = failOnOutOfCapacity || required ? requested.nodes() : Math.min(requested.nodes(), freeNodes.get(defaultResources).size() + totalAllocatedTo(cluster)); - int groups = requested.groups() > capacity ? capacity : requested.groups(); + if (alwaysReturnOneNode) + nodes = 1; + + int groups = requested.groups() > nodes ? nodes : requested.groups(); List allocation = new ArrayList<>(); if (groups == 1) { allocation.addAll(allocateHostGroup(cluster.with(Optional.of(ClusterSpec.Group.from(0))), requested.nodeResources(), - capacity, + nodes, startIndexForClusters, canFail)); } @@ -159,7 +167,7 @@ public class InMemoryProvisioner implements HostProvisioner { for (int i = 0; i < groups; i++) { allocation.addAll(allocateHostGroup(cluster.with(Optional.of(ClusterSpec.Group.from(i))), requested.nodeResources(), - capacity / groups, + nodes / groups, allocation.size(), canFail)); } -- cgit v1.2.3