diff options
7 files changed, 84 insertions, 6 deletions
diff --git a/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apps/clustercontroller/ClusterControllerClusterConfigurer.java b/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apps/clustercontroller/ClusterControllerClusterConfigurer.java index 98e13f64ee8..6c8af75efac 100644 --- a/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apps/clustercontroller/ClusterControllerClusterConfigurer.java +++ b/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apps/clustercontroller/ClusterControllerClusterConfigurer.java @@ -74,6 +74,7 @@ public class ClusterControllerClusterConfigurer { options.minNodeRatioPerGroup = config.min_node_ratio_per_group(); options.setMaxDeferredTaskVersionWaitTime(Duration.ofMillis((int)(config.max_deferred_task_version_wait_time_sec() * 1000))); options.enableMultipleBucketSpaces = config.enable_multiple_bucket_spaces(); + options.clusterHasGlobalDocumentTypes = config.cluster_has_global_document_types(); options.minMergeCompletionRatio = config.min_merge_completion_ratio(); } diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java index e781bf3b145..c2956fe738c 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java @@ -857,8 +857,16 @@ public class FleetController implements NodeStateOrHostInfoChangeHandler, NodeAd } private ClusterStateDeriver createBucketSpaceStateDeriver() { - return new MaintenanceWhenPendingGlobalMerges(stateVersionTracker.createMergePendingChecker(), - createDefaultSpaceMaintenanceTransitionConstraint()); + if (options.clusterHasGlobalDocumentTypes) { + return new MaintenanceWhenPendingGlobalMerges(stateVersionTracker.createMergePendingChecker(), + createDefaultSpaceMaintenanceTransitionConstraint()); + } else { + return createIdentityClonedBucketSpaceStateDeriver(); + } + } + + private static ClusterStateDeriver createIdentityClonedBucketSpaceStateDeriver() { + return (state, space) -> state.clone(); } private MaintenanceTransitionConstraint createDefaultSpaceMaintenanceTransitionConstraint() { diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetControllerOptions.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetControllerOptions.java index 860d38b3438..31268e78338 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetControllerOptions.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetControllerOptions.java @@ -122,6 +122,8 @@ public class FleetControllerOptions implements Cloneable { // TODO replace this flag with a set of bucket spaces instead public boolean enableMultipleBucketSpaces = false; + public boolean clusterHasGlobalDocumentTypes = false; + // TODO: Choose a default value public double minMergeCompletionRatio = 1.0; @@ -232,6 +234,7 @@ public class FleetControllerOptions implements Cloneable { sb.append("<tr><td><nobr>Wanted distribution bits</nobr></td><td align=\"right\">").append(distributionBits).append("</td></tr>"); sb.append("<tr><td><nobr>Max deferred task version wait time</nobr></td><td align=\"right\">").append(maxDeferredTaskVersionWaitTime.toMillis()).append("ms</td></tr>"); sb.append("<tr><td><nobr>Multiple bucket spaces enabled</nobr></td><td align=\"right\">").append(enableMultipleBucketSpaces).append("</td></tr>"); + sb.append("<tr><td><nobr>Cluster has global document types configured</nobr></td><td align=\"right\">").append(clusterHasGlobalDocumentTypes).append("</td></tr>"); sb.append("</table>"); } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MasterElectionTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MasterElectionTest.java index b2464e83f95..07d176745bc 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MasterElectionTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MasterElectionTest.java @@ -502,8 +502,9 @@ public class MasterElectionTest extends FleetControllerTest { startingTest("MasterElectionTest::previously_published_state_is_taken_into_account_for_default_space_when_controller_bootstraps"); FleetControllerOptions options = new FleetControllerOptions("mycluster"); options.enableMultipleBucketSpaces = true; + options.clusterHasGlobalDocumentTypes = true; options.masterZooKeeperCooldownPeriod = 1; - options.minTimeBeforeFirstSystemStateBroadcast = 10000; + options.minTimeBeforeFirstSystemStateBroadcast = 100000; setUpFleetController(3, true, options); setUpVdsNodes(true, new DummyVdsNodeOptions()); fleetController = fleetControllers.get(0); // Required to prevent waitForStableSystem from NPE'ing @@ -540,4 +541,20 @@ public class MasterElectionTest extends FleetControllerTest { waitForStateInAllSpaces("version:\\d+ distributor:10 storage:10"); } + @Test + public void default_space_nodes_not_marked_as_maintenance_when_cluster_has_no_global_document_types() throws Exception { + startingTest("MasterElectionTest::default_space_nodes_not_marked_as_maintenance_when_cluster_has_no_global_document_types"); + FleetControllerOptions options = new FleetControllerOptions("mycluster"); + options.enableMultipleBucketSpaces = true; + options.clusterHasGlobalDocumentTypes = false; + options.masterZooKeeperCooldownPeriod = 1; + options.minTimeBeforeFirstSystemStateBroadcast = 100000; + setUpFleetController(3, true, options); + setUpVdsNodes(true, new DummyVdsNodeOptions()); + fleetController = fleetControllers.get(0); // Required to prevent waitForStableSystem from NPE'ing + waitForMaster(0); + waitForStableSystem(); + waitForStateInAllSpaces("version:\\d+ distributor:10 storage:10"); + } + } 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 c5899655599..0119bced095 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 @@ -597,6 +597,12 @@ public class ContentCluster extends AbstractConfigProducer implements builder.min_storage_up_ratio(0); } builder.enable_multiple_bucket_spaces(enableMultipleBucketSpaces); + // Telling the controller whether we actually _have_ global document types lets + // it selectively enable or disable constraints that aren't needed when these + // are not are present, even if full protocol and backend support is enabled + // for multiple bucket spaces. Basically, if you don't use it, you don't + // pay for it. + builder.cluster_has_global_document_types(enableMultipleBucketSpaces && !globallyDistributedDocuments.isEmpty()); } @Override diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentSearchClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentSearchClusterTest.java index 89492572873..98177b4ada0 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentSearchClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentSearchClusterTest.java @@ -44,15 +44,29 @@ public class ContentSearchClusterTest { createSearchDefinitions("global", "regular")); } - private static ContentCluster createClusterWithMultipleBucketSpacesEnabled() throws Exception { - ContentClusterBuilder builder = createClusterBuilderWithGlobalType(); + private static ContentCluster createClusterFromBuilderAndDocTypes(ContentClusterBuilder builder, String... docTypes) throws Exception { builder.groupXml(joinLines("<group>", "<node distribution-key='0' hostalias='mockhost'/>", "<node distribution-key='1' hostalias='mockhost'/>", "</group>")); builder.enableMultipleBucketSpaces(true); String clusterXml = builder.getXml(); - return createCluster(clusterXml, createSearchDefinitions("global", "regular")); + return createCluster(clusterXml, createSearchDefinitions(docTypes)); + } + + private static ContentCluster createClusterWithMultipleBucketSpacesEnabled() throws Exception { + return createClusterFromBuilderAndDocTypes(createClusterBuilderWithGlobalType(), "global", "regular"); + } + + private static ContentCluster createClusterWithMultipleBucketSpacesEnabledButNoGlobalDocs() throws Exception { + return createClusterFromBuilderAndDocTypes(createClusterBuilderWithOnlyDefaultTypes(), "marve", "fleksnes"); + } + + private static ContentCluster createClusterWithGlobalDocsButNotMultipleSpacesEnabled() throws Exception { + return createCluster(createClusterBuilderWithGlobalType() + .enableMultipleBucketSpaces(false) + .getXml(), + createSearchDefinitions("global", "regular")); } private static ContentClusterBuilder createClusterBuilderWithGlobalType() { @@ -60,6 +74,11 @@ public class ContentSearchClusterTest { .docTypes(Arrays.asList(DocType.indexGlobal("global"), DocType.index("regular"))); } + private static ContentClusterBuilder createClusterBuilderWithOnlyDefaultTypes() { + return new ContentClusterBuilder() + .docTypes(Arrays.asList(DocType.index("marve"), DocType.index("fleksnes"))); + } + private static ProtonConfig getProtonConfig(ContentCluster cluster) { ProtonConfig.Builder protonCfgBuilder = new ProtonConfig.Builder(); cluster.getSearch().getConfig(protonCfgBuilder); @@ -178,4 +197,22 @@ public class ContentSearchClusterTest { } } + @Test + public void cluster_with_global_document_types_sets_cluster_controller_global_docs_config_option() throws Exception { + ContentCluster cluster = createClusterWithMultipleBucketSpacesEnabled(); + assertTrue(getFleetcontrollerConfig(cluster).cluster_has_global_document_types()); + } + + @Test + public void cluster_without_global_document_types_unsets_cluster_controller_global_docs_config_option() throws Exception { + ContentCluster cluster = createClusterWithMultipleBucketSpacesEnabledButNoGlobalDocs(); + assertFalse(getFleetcontrollerConfig(cluster).cluster_has_global_document_types()); + } + + @Test + public void controller_global_documents_config_forced_to_false_if_multiple_spaces_not_enabled() throws Exception { + ContentCluster cluster = createClusterWithGlobalDocsButNotMultipleSpacesEnabled(); + assertFalse(getFleetcontrollerConfig(cluster).cluster_has_global_document_types()); + } + } diff --git a/configdefinitions/src/vespa/fleetcontroller.def b/configdefinitions/src/vespa/fleetcontroller.def index 30620cd2a31..ca7ede28cb2 100644 --- a/configdefinitions/src/vespa/fleetcontroller.def +++ b/configdefinitions/src/vespa/fleetcontroller.def @@ -158,6 +158,12 @@ max_deferred_task_version_wait_time_sec double default=30.0 ## Switch to enable multiple bucket spaces in cluster controller. enable_multiple_bucket_spaces bool default=false +## Whether or not the content cluster the controller has responsibility for +## contains any document types that are tagged as global. If this is true, +## global document-specific behavior is enabled that marks nodes down in the +## default space if they have merges pending in the global bucket space. +cluster_has_global_document_types bool default=false + ## The minimum merge completion ratio of buckets in a bucket space before it is considered complete. ## ## Bucket merges are considered complete when: |