summaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'config-model/src/main/java')
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java7
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java15
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java6
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java130
5 files changed, 38 insertions, 125 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
index 3722876a53f..59930a77a21 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
@@ -37,7 +37,6 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
private Zone zone;
private final Set<ContainerEndpoint> endpoints = Collections.emptySet();
private boolean useDedicatedNodeForLogserver = false;
- private boolean dedicatedClusterControllerCluster = true;
private boolean useThreePhaseUpdates = false;
private double defaultTermwiseLimit = 1.0;
private String jvmGCOptions = null;
@@ -78,7 +77,6 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
@Override public boolean isBootstrap() { return false; }
@Override public boolean isFirstTimeDeployment() { return false; }
@Override public boolean useDedicatedNodeForLogserver() { return useDedicatedNodeForLogserver; }
- @Override public boolean dedicatedClusterControllerCluster() { return hostedVespa && dedicatedClusterControllerCluster; }
@Override public Optional<EndpointCertificateSecrets> endpointCertificateSecrets() { return endpointCertificateSecrets; }
@Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; }
@Override public boolean useThreePhaseUpdates() { return useThreePhaseUpdates; }
@@ -170,11 +168,6 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
return this;
}
- public TestProperties setDedicatedClusterControllerCluster(boolean dedicatedClusterControllerCluster) {
- this.dedicatedClusterControllerCluster = dedicatedClusterControllerCluster;
- return this;
- }
-
public TestProperties setEndpointCertificateSecrets(Optional<EndpointCertificateSecrets> endpointCertificateSecrets) {
this.endpointCertificateSecrets = endpointCertificateSecrets;
return this;
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 0f824fcacf9..188504edd18 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
@@ -142,7 +142,6 @@ public class InMemoryProvisioner implements HostProvisioner {
public List<HostSpec> 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
? requested.nodes()
: Math.min(requested.nodes(), freeNodes.get(defaultResources).size() + totalAllocatedTo(cluster));
@@ -200,7 +199,9 @@ public class InMemoryProvisioner implements HostProvisioner {
for (int i = allocation.size() - 1; i >= 0; i--) {
NodeResources currentResources = allocation.get(0).advertisedResources();
if (currentResources.isUnspecified() || requestedResources.isUnspecified()) continue;
- if ( ! currentResources.compatibleWith(requestedResources)) {
+ if ( (! sharedHosts && ! currentResources.satisfies(requestedResources))
+ ||
+ (sharedHosts && ! currentResources.compatibleWith(requestedResources))) {
HostSpec removed = allocation.remove(i);
freeNodes.put(currentResources, new Host(removed.hostname())); // Return the node back to free pool
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
index 3f346f20144..efae00096df 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
@@ -78,7 +78,7 @@ public class Admin extends AbstractConfigProducer<Admin> implements Serializable
private final FileDistributionConfigProducer fileDistribution;
private final boolean multitenant;
- public Admin(AbstractConfigProducer parent,
+ public Admin(AbstractConfigProducer<?> parent,
Monitoring monitoring,
Metrics metrics,
boolean multitenant,
@@ -186,19 +186,6 @@ public class Admin extends AbstractConfigProducer<Admin> implements Serializable
return fileDistribution;
}
- public List<HostResource> getClusterControllerHosts() {
- List<HostResource> hosts = new ArrayList<>();
- if (multitenant) {
- if (logserver != null)
- hosts.add(logserver.getHostResource());
- } else {
- for (Configserver configserver : getConfigservers()) {
- hosts.add(configserver.getHostResource());
- }
- }
- return hosts;
- }
-
/**
* Adds services to all hosts in the system.
*/
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java
index 72fb1160f7f..ed1dc80d71d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java
@@ -61,9 +61,9 @@ public class ClusterControllerContainer extends Container implements
"/cluster/v2/*",
CLUSTERCONTROLLER_BUNDLE);
addComponent(new AccessLogComponent(containerCluster().orElse(null), AccessLogComponent.AccessLogType.jsonAccessLog,
- AccessLogComponent.CompressionType.GZIP,
- "controller",
- deployState.isHosted()));
+ AccessLogComponent.CompressionType.GZIP,
+ "controller",
+ deployState.isHosted()));
// TODO: Why are bundles added here instead of in the cluster?
addFileBundle("clustercontroller-apps");
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
index 79ce9343560..38eb15819b9 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
@@ -25,6 +25,7 @@ import com.yahoo.vespa.config.content.core.BucketspacesConfig;
import com.yahoo.vespa.config.content.core.StorDistributormanagerConfig;
import com.yahoo.vespa.model.HostResource;
import com.yahoo.vespa.model.admin.Admin;
+import com.yahoo.vespa.model.admin.Configserver;
import com.yahoo.vespa.model.admin.clustercontroller.ClusterControllerCluster;
import com.yahoo.vespa.model.admin.clustercontroller.ClusterControllerComponent;
import com.yahoo.vespa.model.admin.clustercontroller.ClusterControllerConfigurer;
@@ -170,7 +171,7 @@ public class ContentCluster extends AbstractConfigProducer implements
if (context.getParentProducer().getRoot() == null) return c;
- addClusterControllers(context, c.rootGroup, contentElement, c.clusterId, c, deployState);
+ addClusterControllers(context, contentElement, c, deployState);
return c;
}
@@ -284,47 +285,42 @@ public class ContentCluster extends AbstractConfigProducer implements
}
private void addClusterControllers(ConfigModelContext context,
- StorageGroup rootGroup,
ModelElement contentElement,
- String contentClusterName,
ContentCluster contentCluster,
DeployState deployState) {
if (admin == null) return; // only in tests
if (contentCluster.getPersistence() == null) return;
-
ClusterControllerContainerCluster clusterControllers;
-
- ContentCluster overlappingCluster = findOverlappingCluster(context.getParentProducer().getRoot(), contentCluster);
-
- if (overlappingCluster != null && overlappingCluster.getClusterControllers() != null) {
- // Borrow the cluster controllers of the other cluster in this case.
- // This condition only occurs on non-hosted systems with a shared config server,
- // a combination which only exists in system tests.
- clusterControllers = overlappingCluster.getClusterControllers();
+ if (context.properties().hostedVespa()) {
+ clusterControllers = getDedicatedSharedControllers(contentElement, admin, context, deployState);
}
- else if (admin.multitenant()) {
- if (context.properties().dedicatedClusterControllerCluster())
- clusterControllers = getDedicatedSharedControllers(contentElement, admin, context, deployState);
- else {
- clusterControllers = createClusterControllers(new ClusterControllerCluster(contentCluster, "standalone", deployState),
- drawControllerHosts(3, rootGroup),
- contentClusterName + "-controllers",
- true,
- context.getDeployState());
- contentCluster.clusterControllers = clusterControllers;
+ else if (admin.multitenant()) { // system tests: Put on logserver
+ if (admin.getClusterControllers() == null) {
+ // TODO: logserver== null only obtains in unit tests, disallow it
+ List<HostResource> host = admin.getLogserver() == null ? List.of() : List.of(admin.getLogserver().getHostResource());
+ admin.setClusterControllers(createClusterControllers(new ClusterControllerCluster(admin, "standalone", deployState),
+ host,
+ "cluster-controllers",
+ true,
+ deployState));
}
- }
- else {
clusterControllers = admin.getClusterControllers();
- if (clusterControllers == null) {
- List<HostResource> hosts = admin.getClusterControllerHosts();
+ }
+ else { // self hosted: Put on config servers or explicit cluster controllers
+ if (admin.getClusterControllers() == null) {
+ var hosts = admin.getConfigservers().stream().map(s -> s.getHostResource()).collect(toList());
if (hosts.size() > 1) {
- context.getDeployState().getDeployLogger().log(Level.INFO,
- "When having content cluster(s) and more than 1 config server it is recommended to configure cluster controllers explicitly.");
+ var message = "When having content clusters and more than 1 config server " +
+ "it is recommended to configure cluster controllers explicitly.";
+ deployState.getDeployLogger().log(Level.INFO, message);
}
- clusterControllers = createClusterControllers(admin, hosts, "cluster-controllers", false, context.getDeployState());
- admin.setClusterControllers(clusterControllers);
+ admin.setClusterControllers(createClusterControllers(admin,
+ hosts,
+ "cluster-controllers",
+ false,
+ deployState));
}
+ clusterControllers = admin.getClusterControllers();
}
addClusterControllerComponentsForThisCluster(clusterControllers, contentCluster);
@@ -334,21 +330,6 @@ public class ContentCluster extends AbstractConfigProducer implements
}
}
- /** Returns any other content cluster which shares nodes with this, or null if none are built */
- private ContentCluster findOverlappingCluster(AbstractConfigProducerRoot root, ContentCluster contentCluster) {
- for (ContentCluster otherContentCluster : root.getChildrenByTypeRecursive(ContentCluster.class)) {
- if (otherContentCluster != contentCluster && overlaps(contentCluster, otherContentCluster))
- return otherContentCluster;
- }
- return null;
- }
-
- private boolean overlaps(ContentCluster c1, ContentCluster c2) {
- Set<HostResource> c1Hosts = c1.getRootGroup().recursiveGetNodes().stream().map(StorageNode::getHostResource).collect(Collectors.toSet());
- Set<HostResource> c2Hosts = c2.getRootGroup().recursiveGetNodes().stream().map(StorageNode::getHostResource).collect(Collectors.toSet());
- return ! Sets.intersection(c1Hosts, c2Hosts).isEmpty();
- }
-
public static final NodeResources clusterControllerResources = new NodeResources(0.5, 2, 10, 0.3, NodeResources.DiskSpeed.any, NodeResources.StorageType.any);
private ClusterControllerContainerCluster getDedicatedSharedControllers(ModelElement contentElement, Admin admin,
@@ -375,65 +356,19 @@ public class ContentCluster extends AbstractConfigProducer implements
return admin.getClusterControllers();
}
- private List<HostResource> drawControllerHosts(int count, StorageGroup rootGroup) {
- List<HostResource> hosts = drawControllerHosts(count, false, rootGroup);
- List<HostResource> retiredHosts = drawControllerHosts(count, true, rootGroup);
-
- // preserve the cluster state in case all pre-existing controllers are on retired nodes
- List<HostResource> all = new ArrayList<>(hosts);
- all.addAll(retiredHosts);
- return all;
- }
-
- private List<HostResource> drawControllerHosts(int count, boolean retired, StorageGroup rootGroup) {
- List<HostResource> hosts = drawContentHostsRecursively(count, retired, rootGroup);
- if (hosts.size() % 2 == 0 && ! hosts.isEmpty()) // ZK clusters of even sizes are less available (even in the size=2 case)
- hosts = hosts.subList(0, hosts.size()-1);
- return hosts;
- }
-
- /**
- * Draw <code>count</code> nodes from as many different content groups below this as possible.
- * This will only achieve maximum spread in the case where the groups are balanced and never on the same
- * physical node. It will not achieve maximum spread over all levels in a multilevel group hierarchy.
- */
- // Note: This method cannot be changed to draw different nodes without ensuring that it will draw nodes
- // which overlaps with previously drawn nodes as that will prevent rolling upgrade
- private List<HostResource> drawContentHostsRecursively(int count, boolean retired, StorageGroup group) {
- Set<HostResource> hosts = new HashSet<>();
- if (group.getNodes().isEmpty()) {
- int hostsPerSubgroup = (int)Math.ceil((double)count / group.getSubgroups().size());
- for (StorageGroup subgroup : group.getSubgroups())
- hosts.addAll(drawContentHostsRecursively(hostsPerSubgroup, retired, subgroup));
- }
- else {
- hosts.addAll(group.getNodes().stream()
- .filter(node -> node.isRetired() == retired)
- .map(StorageNode::getHostResource).collect(toList()));
- }
-
- List<HostResource> sortedHosts = new ArrayList<>(hosts);
- sortedHosts.sort(HostResource::comparePrimarilyByIndexTo);
- sortedHosts = sortedHosts.subList(0, Math.min(count, hosts.size()));
- return sortedHosts;
- }
-
private ClusterControllerContainerCluster createClusterControllers(AbstractConfigProducer<?> parent,
Collection<HostResource> hosts,
String name,
- boolean multitenant,
+ boolean runStandaloneZooKeeper,
DeployState deployState) {
var clusterControllers = new ClusterControllerContainerCluster(parent, name, name, deployState);
List<ClusterControllerContainer> containers = new ArrayList<>();
- // Add a cluster controller on each config server (there is always at least one).
if (clusterControllers.getContainers().isEmpty()) {
int index = 0;
for (HostResource host : hosts) {
- int ccIndex = deployState.getProperties().dedicatedClusterControllerCluster()
- ? host.spec().membership().map(ClusterMembership::index).orElse(index)
- : index;
+ int ccIndex = host.spec().membership().map(ClusterMembership::index).orElse(index);
boolean retired = host.spec().membership().map(ClusterMembership::retired).orElse(false);
- var clusterControllerContainer = new ClusterControllerContainer(clusterControllers, ccIndex, multitenant, deployState, retired);
+ var clusterControllerContainer = new ClusterControllerContainer(clusterControllers, ccIndex, runStandaloneZooKeeper, deployState, retired);
clusterControllerContainer.setHostResource(host);
clusterControllerContainer.initService(deployState.getDeployLogger());
clusterControllerContainer.setProp("clustertype", "admin");
@@ -511,11 +446,7 @@ public class ContentCluster extends AbstractConfigProducer implements
public PersistenceEngine.PersistenceFactory getPersistence() { return persistenceFactory; }
- /**
- * The list of documentdefinitions declared at the cluster level.
- *
- * @return the set of documenttype names
- */
+ /** Returns a list of th document types declared at the cluster level. */
public Map<String, NewDocumentType> getDocumentDefinitions() { return documentDefinitions; }
public boolean isGloballyDistributed(NewDocumentType docType) {
@@ -753,6 +684,7 @@ public class ContentCluster extends AbstractConfigProducer implements
* a previous generation of it only by restarting the consuming processes.
*/
public void setDeferChangesUntilRestart(boolean deferChangesUntilRestart) {
+ // TODO
}
}