diff options
author | Jon Bratseth <bratseth@gmail.com> | 2020-06-23 17:36:42 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2020-06-23 17:36:42 +0200 |
commit | eb190cf69addb19cfdf2f7b43b5191192ba9d9b4 (patch) | |
tree | ba41974f52ea4ad92449c2eee545f8207a8adc0c /node-repository/src/main | |
parent | c1313421e3f7ec8b10c61d8e317e190edcd2be8c (diff) |
From 0 to 1 spare
Diffstat (limited to 'node-repository/src/main')
4 files changed, 19 insertions, 11 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java index bec35e7ee4f..ff65dc18181 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java @@ -8,6 +8,7 @@ import com.yahoo.component.Version; import com.yahoo.concurrent.maintenance.JobControl; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.DockerImage; +import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.Flavor; import com.yahoo.config.provision.NodeFlavors; import com.yahoo.config.provision.NodeType; @@ -103,6 +104,7 @@ public class NodeRepository extends AbstractComponent { private final JobControl jobControl; private final Applications applications; private final boolean canProvisionHosts; + private final int spareCount; /** * Creates a node repository from a zookeeper provider. @@ -121,7 +123,8 @@ public class NodeRepository extends AbstractComponent { zone, new DnsNameResolver(), DockerImage.fromString(config.dockerImage()), config.useCuratorClientCache(), - provisionServiceProvider.getHostProvisioner().isPresent()); + provisionServiceProvider.getHostProvisioner().isPresent(), + zone.environment() == Environment.prod ? 1 : 0); } /** @@ -136,7 +139,8 @@ public class NodeRepository extends AbstractComponent { NameResolver nameResolver, DockerImage dockerImage, boolean useCuratorClientCache, - boolean canProvisionHosts) { + boolean canProvisionHosts, + int spareCount) { this.db = new CuratorDatabaseClient(flavors, curator, clock, zone, useCuratorClientCache); this.zone = zone; this.clock = clock; @@ -150,6 +154,7 @@ public class NodeRepository extends AbstractComponent { this.jobControl = new JobControl(db); this.applications = new Applications(db); this.canProvisionHosts = canProvisionHosts; + this.spareCount = spareCount; // read and write all nodes to make sure they are stored in the latest version of the serialized format for (State state : State.values()) @@ -192,6 +197,9 @@ public class NodeRepository extends AbstractComponent { public HostResourcesCalculator resourcesCalculator() { return resourcesCalculator; } + /** The number of nodes we should ensure has free capacity for node failures whenever possible */ + public int spareCount() { return spareCount; } + // ---------------- Query API ---------------------------------------------------------------- /** diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/SpareCapacityMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/SpareCapacityMaintainer.java index 54899372397..c8c66a77d60 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/SpareCapacityMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/SpareCapacityMaintainer.java @@ -48,7 +48,7 @@ public class SpareCapacityMaintainer extends NodeRepositoryMaintainer { Duration interval) { this(deployer, nodeRepository, metric, interval, 10_000 // Should take less than a few minutes - ); + ); } public SpareCapacityMaintainer(Deployer deployer, @@ -103,10 +103,11 @@ public class SpareCapacityMaintainer extends NodeRepositoryMaintainer { Node node = nodeWhichCantMove.get(); NodeList allNodes = nodeRepository().list(); - // Allocation will assign the two most empty nodes as "spares", which will not be allocated on + // Allocation will assign the spareCount most empty nodes as "spares", which will not be allocated on // unless needed for node failing. Our goal here is to make room on these spares for the given node HostCapacity hostCapacity = new HostCapacity(allNodes, nodeRepository().resourcesCalculator()); - Set<Node> spareHosts = hostCapacity.findSpareHosts(allNodes.hosts().satisfies(node.resources()).asList(), 2); + Set<Node> spareHosts = hostCapacity.findSpareHosts(allNodes.hosts().satisfies(node.resources()).asList(), + nodeRepository().spareCount()); List<Node> hosts = allNodes.hosts().except(spareHosts).asList(); CapacitySolver capacitySolver = new CapacitySolver(hostCapacity, maxIterations); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java index f9d8213072e..faae52c72ec 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java @@ -46,8 +46,6 @@ import java.util.logging.Logger; public class NodeRepositoryProvisioner implements Provisioner { private static final Logger log = Logger.getLogger(NodeRepositoryProvisioner.class.getName()); - private static final int SPARE_CAPACITY_PROD = 0; - private static final int SPARE_CAPACITY_NONPROD = 0; private final NodeRepository nodeRepository; private final AllocationOptimizer allocationOptimizer; @@ -69,13 +67,14 @@ public class NodeRepositoryProvisioner implements Provisioner { .map(lbService -> new LoadBalancerProvisioner(nodeRepository, lbService, flagSource)); this.nodeResourceLimits = new NodeResourceLimits(nodeRepository); this.preparer = new Preparer(nodeRepository, - zone.environment() == Environment.prod ? SPARE_CAPACITY_PROD : SPARE_CAPACITY_NONPROD, + nodeRepository.spareCount(), provisionServiceProvider.getHostProvisioner(), flagSource, loadBalancerProvisioner); this.activator = new Activator(nodeRepository, loadBalancerProvisioner); } + /** * Returns a list of nodes in the prepared or active state, matching the given constraints. * The nodes are ordered by increasing index number. @@ -133,8 +132,6 @@ public class NodeRepositoryProvisioner implements Provisioner { loadBalancerProvisioner.ifPresent(lbProvisioner -> lbProvisioner.deactivate(application, transaction)); } - int getSpareCapacityProd() { return SPARE_CAPACITY_PROD; } - /** * Returns the target cluster resources, a value between the min and max in the requested capacity, * and updates the application store with the received min and max. diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java index 151bd80a7b7..bf56be4598c 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java @@ -64,7 +64,9 @@ public class MockNodeRepository extends NodeRepository { Zone.defaultZone(), new MockNameResolver().mockAnyLookup(), DockerImage.fromString("docker-registry.domain.tld:8080/dist/vespa"), - true, false); + true, + false, + 0); this.flavors = flavors; curator.setZooKeeperEnsembleConnectionSpec("cfg1:1234,cfg2:1234,cfg3:1234"); |