diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-04-27 13:28:25 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2021-04-27 13:28:25 +0200 |
commit | 7735a7c61f221005cec272fe8c83b31e407ea18e (patch) | |
tree | e95f89d08f99708deb3ec98b705bf85dfb8ab9bc /config-model/src | |
parent | 33b310ebd7fc46564ff6d9c15dcc0a559f7e34ff (diff) |
Control use of fsync in services.xml.
Diffstat (limited to 'config-model/src')
6 files changed, 64 insertions, 14 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java index a4322976992..675cbb494dd 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java @@ -44,6 +44,7 @@ import static java.util.stream.Collectors.toList; public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> implements ProtonConfig.Producer, DispatchConfig.Producer { private final boolean flushOnShutdown; + private final boolean syncTransactionLog; /** If this is set up for streaming search, it is modelled as one search cluster per search definition */ private final Map<String, AbstractSearchCluster> clusters = new TreeMap<>(); @@ -97,13 +98,15 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> ModelElement clusterElem = new ModelElement(producerSpec); String clusterName = ContentCluster.getClusterId(clusterElem); Boolean flushOnShutdownElem = clusterElem.childAsBoolean("engine.proton.flush-on-shutdown"); + Boolean syncTransactionLog = clusterElem.childAsBoolean("engine.proton.sync-transactionlog"); ContentSearchCluster search = new ContentSearchCluster(ancestor, clusterName, deployState.getProperties().featureFlags(), documentDefinitions, globallyDistributedDocuments, - getFlushOnShutdown(flushOnShutdownElem, deployState), + getFlushOnShutdown(flushOnShutdownElem), + getSyncTransactionLog(syncTransactionLog, deployState), combined); ModelElement tuning = clusterElem.childByPath("engine.proton.tuning"); @@ -117,12 +120,18 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> return search; } - private boolean getFlushOnShutdown(Boolean flushOnShutdownElem, DeployState deployState) { + private boolean getFlushOnShutdown(Boolean flushOnShutdownElem) { if (flushOnShutdownElem != null) { return flushOnShutdownElem; } return true; } + private boolean getSyncTransactionLog(Boolean syncTransactionLogElem, DeployState deployState) { + if (syncTransactionLogElem != null) { + return syncTransactionLogElem; + } + return true; + } private Double getQueryTimeout(ModelElement clusterElem) { return clusterElem.childAsDouble("engine.proton.query-timeout"); @@ -197,6 +206,7 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> Map<String, NewDocumentType> documentDefinitions, Set<NewDocumentType> globallyDistributedDocuments, boolean flushOnShutdown, + boolean syncTransactionLog, boolean combined) { super(parent, "search"); @@ -204,6 +214,8 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> this.documentDefinitions = documentDefinitions; this.globallyDistributedDocuments = globallyDistributedDocuments; this.flushOnShutdown = flushOnShutdown; + this.syncTransactionLog = syncTransactionLog; + this.combined = combined; maxPendingMoveOps = featureFlags.maxPendingMoveOps(); feedSequencerType = convertFeedSequencerType(featureFlags.feedSequencerType()); @@ -278,12 +290,12 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> searchNode.setHostResource(node.getHostResource()); searchNode.initService(deployState.getDeployLogger()); - tls = new TransactionLogServer(searchNode, clusterName); + tls = new TransactionLogServer(searchNode, clusterName, syncTransactionLog); tls.setHostResource(searchNode.getHostResource()); tls.initService(deployState.getDeployLogger()); } else { searchNode = new SearchNode.Builder(""+node.getDistributionKey(), spec, clusterName, node, flushOnShutdown, tuning, resourceLimits, combined).build(deployState, parent, element.getXml()); - tls = new TransactionLogServer.Builder(clusterName).build(deployState, searchNode, element.getXml()); + tls = new TransactionLogServer.Builder(clusterName, syncTransactionLog).build(deployState, searchNode, element.getXml()); } searchNode.setTls(tls); if (hasIndexedCluster()) { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/TransactionLogServer.java b/config-model/src/main/java/com/yahoo/vespa/model/search/TransactionLogServer.java index 7c3f9bc1001..c24fa6396e7 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/TransactionLogServer.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/search/TransactionLogServer.java @@ -25,9 +25,11 @@ public class TransactionLogServer extends AbstractService { } } - public TransactionLogServer(AbstractConfigProducer searchNode, String clusterName) { + private final boolean useFsync; + public TransactionLogServer(AbstractConfigProducer searchNode, String clusterName, boolean useFsync) { super(searchNode, "transactionlogserver"); portsMeta.on(0).tag("tls"); + this.useFsync = useFsync; setProp("clustername", clusterName); setProp("clustertype", "search"); } @@ -35,13 +37,15 @@ public class TransactionLogServer extends AbstractService { public static class Builder extends VespaDomBuilder.DomConfigProducerBuilder<TransactionLogServer> { private final String clusterName; - public Builder(String clusterName) { + private final boolean useFsync; + public Builder(String clusterName, boolean useFsync) { this.clusterName = clusterName; + this.useFsync = useFsync; } @Override protected TransactionLogServer doBuild(DeployState deployState, AbstractConfigProducer ancestor, Element producerSpec) { - return new TransactionLogServer(ancestor, clusterName); + return new TransactionLogServer(ancestor, clusterName, useFsync); } } @@ -75,7 +79,10 @@ public class TransactionLogServer extends AbstractService { } public void getConfig(TranslogserverConfig.Builder builder) { - builder.listenport(getTlsPort()).basedir(getTlsDir()); + builder + .listenport(getTlsPort()) + .basedir(getTlsDir()) + .usefsync(useFsync); } diff --git a/config-model/src/main/resources/schema/content.rnc b/config-model/src/main/resources/schema/content.rnc index a48d38b9f2c..7f52eae6da8 100644 --- a/config-model/src/main/resources/schema/content.rnc +++ b/config-model/src/main/resources/schema/content.rnc @@ -167,6 +167,7 @@ Engine = element engine { Proton = element proton { element flush-on-shutdown { xsd:string }? & + element sync-transactionlog { xsd:string }? & element visibility-delay { xsd:double { minInclusive = "0.0" } }? & element query-timeout { xsd:double { minInclusive = "0.0" } }? & element searchable-copies { xsd:integer { minInclusive = "0" } }? & 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 5fd4885a1f2..46bd005deb6 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 @@ -3,6 +3,7 @@ package com.yahoo.vespa.model.content; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.deploy.TestProperties; +import com.yahoo.searchlib.TranslogserverConfig; import com.yahoo.vespa.config.content.FleetcontrollerConfig; import com.yahoo.vespa.config.content.AllClustersBucketSpacesConfig; import com.yahoo.vespa.config.content.core.BucketspacesConfig; @@ -246,4 +247,16 @@ public class ContentSearchClusterTest { assertFalse(getFleetcontrollerConfig(cluster).cluster_has_global_document_types()); } + TranslogserverConfig getTlsConfig(ContentCluster cluster) { + TranslogserverConfig.Builder tlsBuilder = new TranslogserverConfig.Builder(); + cluster.getSearch().getSearchNodes().get(0).getConfig(tlsBuilder); + return tlsBuilder.build(); + } + + @Test + public void fsync_is_controllable() throws Exception { + assertTrue(getTlsConfig(createCluster(new ContentClusterBuilder().getXml())).usefsync()); + assertTrue(getTlsConfig(createCluster(new ContentClusterBuilder().syncTransactionLog(true).getXml())).usefsync()); + assertFalse(getTlsConfig(createCluster(new ContentClusterBuilder().syncTransactionLog(false).getXml())).usefsync()); + } } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/utils/ContentClusterBuilder.java b/config-model/src/test/java/com/yahoo/vespa/model/content/utils/ContentClusterBuilder.java index 491326fdc9c..d97aeffb107 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/utils/ContentClusterBuilder.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/utils/ContentClusterBuilder.java @@ -28,6 +28,7 @@ public class ContentClusterBuilder { private Optional<Double> protonMemoryLimit = Optional.empty(); private Optional<Double> clusterControllerDiskLimit = Optional.empty(); private Optional<Double> clusterControllerMemoryLimit = Optional.empty(); + private Optional<Boolean> syncTransactionLog = Optional.empty(); public ContentClusterBuilder() { } @@ -42,6 +43,11 @@ public class ContentClusterBuilder { return this; } + public ContentClusterBuilder syncTransactionLog(boolean syncTransactionLog) { + this.syncTransactionLog = Optional.of(syncTransactionLog); + return this; + } + public ContentClusterBuilder searchableCopies(int searchableCopies) { this.searchableCopies = searchableCopies; return this; @@ -101,6 +107,7 @@ public class ContentClusterBuilder { " <proton>", " <searchable-copies>" + searchableCopies + "</searchable-copies>", getProtonResourceLimitsXml(" "), + getTransactionLogSyncXml(" "), " </proton>", " </engine>"); if (dispatchXml.isPresent()) { @@ -138,7 +145,11 @@ public class ContentClusterBuilder { return ""; } - private static String getXmlLine(String tag, Optional<Double> value, String indent) { + private String getTransactionLogSyncXml(String indent) { + return getXmlLine("sync-transactionlog", syncTransactionLog, indent); + } + + private static <T> String getXmlLine(String tag, Optional<T> value, String indent) { if (value.isPresent()) { return indent + "<" + tag + ">" + value.get() + "</" + tag + ">\n"; } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchNodeTest.java b/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchNodeTest.java index e270c81fe78..cb98dd3387e 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchNodeTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchNodeTest.java @@ -38,9 +38,9 @@ public class SearchNodeTest { assertEquals(expected, cfg.basedir()); } - private void prepare(MockRoot root, SearchNode node) { + private void prepare(MockRoot root, SearchNode node, boolean useFsync) { Host host = new Host(root, "mockhost"); - TransactionLogServer tls = new TransactionLogServer(root, "mycluster"); + TransactionLogServer tls = new TransactionLogServer(root, "mycluster", useFsync); tls.setHostResource(new HostResource(host)); tls.setBasePort(100); tls.initService(root.deployLogger()); @@ -61,10 +61,16 @@ public class SearchNodeTest { } @Test + public void requireThatSyncIsHonoured() { + assertTrue(getTlsConfig(new TestProperties(), true).usefsync()); + assertFalse(getTlsConfig(new TestProperties(), false).usefsync()); + } + + @Test public void requireThatBasedirIsCorrectForElasticMode() { MockRoot root = new MockRoot(""); SearchNode node = createSearchNode(root, "mynode", 3, new NodeSpec(7, 5), false, root.getDeployState().isHosted(), false); - prepare(root, node); + prepare(root, node, true); assertBaseDir(Defaults.getDefaults().underVespaHome("var/db/vespa/search/cluster.mycluster/n3"), node); } @@ -92,10 +98,10 @@ public class SearchNodeTest { return new MockRoot("", new DeployState.Builder().properties(properties).build()); } - private TranslogserverConfig getTlsConfig(ModelContext.Properties properties) { + private TranslogserverConfig getTlsConfig(ModelContext.Properties properties, boolean useFsync) { MockRoot root = createRoot(properties); SearchNode node = createSearchNode(root); - prepare(root, node); + prepare(root, node, useFsync); TranslogserverConfig.Builder tlsBuilder = new TranslogserverConfig.Builder(); node.getConfig(tlsBuilder); return tlsBuilder.build(); |