From 5d664f3d683a0e546a1d72a18a5f2c3c4a053171 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Fri, 13 May 2022 14:25:04 +0200 Subject: Control code loading for proton with feature flag 'load-code-as-hugepages' --- .../vespa/model/content/ContentSearchCluster.java | 4 +- .../com/yahoo/vespa/model/search/SearchNode.java | 24 ++-- .../vespa/model/search/test/SchemaNodeTest.java | 108 ------------------ .../vespa/model/search/test/SearchNodeTest.java | 122 +++++++++++++++++++++ 4 files changed, 135 insertions(+), 123 deletions(-) delete mode 100644 config-model/src/test/java/com/yahoo/vespa/model/search/test/SchemaNodeTest.java create mode 100644 config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchNodeTest.java (limited to 'config-model') 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 82321216519..8b9f32fa135 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 @@ -273,8 +273,8 @@ public class ContentSearchCluster extends AbstractConfigProducer Optional tuning = Optional.ofNullable(this.tuning); if (element == null) { searchNode = SearchNode.create(parent, "" + node.getDistributionKey(), node.getDistributionKey(), spec, - clusterName, node, flushOnShutdown, tuning, resourceLimits, parentGroup.isHosted(), - fractionOfMemoryReserved); + clusterName, node, flushOnShutdown, tuning, resourceLimits, deployState.isHosted(), + deployState.featureFlags().loadCodeAsHugePages(), fractionOfMemoryReserved); searchNode.setHostResource(node.getHostResource()); searchNode.initService(deployState); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java b/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java index 6e3f3e1ebf5..e7c0968f99e 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java @@ -95,8 +95,9 @@ public class SearchNode extends AbstractService implements @Override protected SearchNode doBuild(DeployState deployState, AbstractConfigProducer ancestor, Element producerSpec) { - return new SearchNode(ancestor, name, contentNode.getDistributionKey(), nodeSpec, clusterName, contentNode, - flushOnShutdown, tuning, resourceLimits, deployState.isHosted(), fractionOfMemoryReserved); + return SearchNode.create(ancestor, name, contentNode.getDistributionKey(), nodeSpec, clusterName, contentNode, + flushOnShutdown, tuning, resourceLimits, deployState.isHosted(), + deployState.featureFlags().loadCodeAsHugePages(), fractionOfMemoryReserved); } } @@ -104,26 +105,22 @@ public class SearchNode extends AbstractService implements public static SearchNode create(AbstractConfigProducer parent, String name, int distributionKey, NodeSpec nodeSpec, String clusterName, AbstractService serviceLayerService, boolean flushOnShutdown, Optional tuning, Optional resourceLimits, boolean isHostedVespa, - double fractionOfMemoryReserved) { + boolean loadCodeAsHugePages, double fractionOfMemoryReserved) { return new SearchNode(parent, name, distributionKey, nodeSpec, clusterName, serviceLayerService, flushOnShutdown, - tuning, resourceLimits, isHostedVespa, fractionOfMemoryReserved); + tuning, resourceLimits, isHostedVespa, loadCodeAsHugePages, fractionOfMemoryReserved); } private SearchNode(AbstractConfigProducer parent, String name, int distributionKey, NodeSpec nodeSpec, String clusterName, AbstractService serviceLayerService, boolean flushOnShutdown, Optional tuning, Optional resourceLimits, boolean isHostedVespa, - double fractionOfMemoryReserved) { - this(parent, name, nodeSpec, clusterName, flushOnShutdown, tuning, resourceLimits, isHostedVespa, fractionOfMemoryReserved); + boolean loadCodeAsHugePages, double fractionOfMemoryReserved) { + super(parent, name); this.distributionKey = distributionKey; this.serviceLayerService = serviceLayerService; - setPropertiesElastic(clusterName, distributionKey); - } - - private SearchNode(AbstractConfigProducer parent, String name, NodeSpec nodeSpec, String clusterName, - boolean flushOnShutdown, Optional tuning, Optional resourceLimits, boolean isHostedVespa, - double fractionOfMemoryReserved) { - super(parent, name); this.isHostedVespa = isHostedVespa; + if (loadCodeAsHugePages) { + addEnvironmentVariable("VESPA_LOAD_CODE_AS_HUGEPAGES", "true"); + } this.fractionOfMemoryReserved = fractionOfMemoryReserved; this.nodeSpec = nodeSpec; this.clusterName = clusterName; @@ -136,6 +133,7 @@ public class SearchNode extends AbstractService implements // Properties are set in DomSearchBuilder this.tuning = tuning; this.resourceLimits = resourceLimits; + setPropertiesElastic(clusterName, distributionKey); } private void setPropertiesElastic(String clusterName, int distributionKey) { diff --git a/config-model/src/test/java/com/yahoo/vespa/model/search/test/SchemaNodeTest.java b/config-model/src/test/java/com/yahoo/vespa/model/search/test/SchemaNodeTest.java deleted file mode 100644 index a347c0a9c43..00000000000 --- a/config-model/src/test/java/com/yahoo/vespa/model/search/test/SchemaNodeTest.java +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.model.search.test; - -import com.yahoo.config.model.api.ModelContext; -import com.yahoo.config.model.deploy.DeployState; -import com.yahoo.config.model.deploy.TestProperties; -import com.yahoo.config.model.test.MockRoot; -import com.yahoo.searchlib.TranslogserverConfig; -import com.yahoo.vespa.config.search.core.ProtonConfig; -import com.yahoo.vespa.defaults.Defaults; -import com.yahoo.vespa.model.Host; -import com.yahoo.vespa.model.HostResource; -import com.yahoo.vespa.model.search.NodeSpec; -import com.yahoo.vespa.model.search.SearchNode; -import com.yahoo.vespa.model.search.TransactionLogServer; -import org.junit.Test; - -import java.util.Optional; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Unit tests for search node. - * - * @author geirst - */ -public class SchemaNodeTest { - - private void assertBaseDir(String expected, SearchNode node) { - ProtonConfig.Builder builder = new ProtonConfig.Builder(); - node.getConfig(builder); - ProtonConfig cfg = new ProtonConfig(builder); - assertEquals(expected, cfg.basedir()); - } - - private void prepare(MockRoot root, SearchNode node, Boolean useFsync) { - Host host = new Host(root, "mockhost"); - TransactionLogServer tls = new TransactionLogServer(root, "mycluster", useFsync); - tls.setHostResource(new HostResource(host)); - tls.setBasePort(100); - tls.initService(root.getDeployState()); - node.setTls(tls); - node.setHostResource(new HostResource(host)); - node.setBasePort(200); - node.initService(root.getDeployState()); - root.freezeModelTopology(); - } - - private static SearchNode createSearchNode(MockRoot root, String name, int distributionKey, - NodeSpec nodeSpec, boolean flushOnShutDown, boolean isHosted) { - return SearchNode.create(root, name, distributionKey, nodeSpec, "mycluster", null, flushOnShutDown, - Optional.empty(), Optional.empty(), isHosted, 0.0); - } - - private static SearchNode createSearchNode(MockRoot root) { - return createSearchNode(root, "mynode", 3, new NodeSpec(7, 5), true, true); - } - - @Test - public void requireThatSyncIsHonoured() { - assertTrue(getTlsConfig(new TestProperties(), null).usefsync()); - 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()); - prepare(root, node, true); - assertBaseDir(Defaults.getDefaults().underVespaHome("var/db/vespa/search/cluster.mycluster/n3"), node); - } - - @Test - public void requireThatPreShutdownCommandIsEmptyWhenNotActivated() { - MockRoot root = new MockRoot(""); - SearchNode node = createSearchNode(root, "mynode", 3, new NodeSpec(7, 5), false, root.getDeployState().isHosted()); - node.setHostResource(new HostResource(new Host(node, "mynbode"))); - node.initService(root.getDeployState()); - assertFalse(node.getPreShutdownCommand().isPresent()); - } - - @Test - public void requireThatPreShutdownCommandUsesPrepareRestartWhenActivated() { - MockRoot root = new MockRoot(""); - SearchNode node = createSearchNode(root, "mynode2", 4, new NodeSpec(7, 5), true, root.getDeployState().isHosted()); - node.setHostResource(new HostResource(new Host(node, "mynbode2"))); - node.initService(root.getDeployState()); - assertTrue(node.getPreShutdownCommand().isPresent()); - assertTrue(node.getPreShutdownCommand().get().contains("vespa-proton-cmd " + node.getRpcPort() + " prepareRestart")); - } - - private MockRoot createRoot(ModelContext.Properties properties) { - return new MockRoot("", new DeployState.Builder().properties(properties).build()); - } - - private TranslogserverConfig getTlsConfig(ModelContext.Properties properties, Boolean useFsync) { - MockRoot root = createRoot(properties); - SearchNode node = createSearchNode(root); - prepare(root, node, useFsync); - TranslogserverConfig.Builder tlsBuilder = new TranslogserverConfig.Builder(); - node.getConfig(tlsBuilder); - return tlsBuilder.build(); - } - -} 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 new file mode 100644 index 00000000000..cbd6ac4bea9 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchNodeTest.java @@ -0,0 +1,122 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.search.test; + +import com.yahoo.config.model.api.ModelContext; +import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.model.deploy.TestProperties; +import com.yahoo.config.model.test.MockRoot; +import com.yahoo.searchlib.TranslogserverConfig; +import com.yahoo.vespa.config.search.core.ProtonConfig; +import com.yahoo.vespa.defaults.Defaults; +import com.yahoo.vespa.model.Host; +import com.yahoo.vespa.model.HostResource; +import com.yahoo.vespa.model.search.NodeSpec; +import com.yahoo.vespa.model.search.SearchNode; +import com.yahoo.vespa.model.search.TransactionLogServer; +import org.junit.Test; + +import java.util.Optional; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Unit tests for search node. + * + * @author geirst + */ +public class SearchNodeTest { + + private void assertBaseDir(String expected, SearchNode node) { + ProtonConfig.Builder builder = new ProtonConfig.Builder(); + node.getConfig(builder); + ProtonConfig cfg = new ProtonConfig(builder); + assertEquals(expected, cfg.basedir()); + } + + private void prepare(MockRoot root, SearchNode node, Boolean useFsync) { + Host host = new Host(root, "mockhost"); + TransactionLogServer tls = new TransactionLogServer(root, "mycluster", useFsync); + tls.setHostResource(new HostResource(host)); + tls.setBasePort(100); + tls.initService(root.getDeployState()); + node.setTls(tls); + node.setHostResource(new HostResource(host)); + node.setBasePort(200); + node.initService(root.getDeployState()); + root.freezeModelTopology(); + } + + private static SearchNode createSearchNode(MockRoot root, String name, int distributionKey, + NodeSpec nodeSpec, boolean flushOnShutDown, boolean isHosted, boolean loadCodeAsHugePages) { + return SearchNode.create(root, name, distributionKey, nodeSpec, "mycluster", null, flushOnShutDown, + Optional.empty(), Optional.empty(), isHosted, loadCodeAsHugePages, 0.0); + } + + private static SearchNode createSearchNode(MockRoot root) { + return createSearchNode(root, "mynode", 3, new NodeSpec(7, 5), true, true, false); + } + + @Test + public void requireThatSyncIsHonoured() { + assertTrue(getTlsConfig(new TestProperties(), null).usefsync()); + 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, true); + assertBaseDir(Defaults.getDefaults().underVespaHome("var/db/vespa/search/cluster.mycluster/n3"), node); + } + + @Test + public void requireThatPreShutdownCommandIsEmptyWhenNotActivated() { + MockRoot root = new MockRoot(""); + SearchNode node = createSearchNode(root, "mynode", 3, new NodeSpec(7, 5), false, root.getDeployState().isHosted(), false); + node.setHostResource(new HostResource(new Host(node, "mynbode"))); + node.initService(root.getDeployState()); + assertFalse(node.getPreShutdownCommand().isPresent()); + } + + @Test + public void requireThatPreShutdownCommandUsesPrepareRestartWhenActivated() { + MockRoot root = new MockRoot(""); + SearchNode node = createSearchNode(root, "mynode2", 4, new NodeSpec(7, 5), true, root.getDeployState().isHosted(), false); + node.setHostResource(new HostResource(new Host(node, "mynbode2"))); + node.initService(root.getDeployState()); + assertTrue(node.getPreShutdownCommand().isPresent()); + assertTrue(node.getPreShutdownCommand().get().contains("vespa-proton-cmd " + node.getRpcPort() + " prepareRestart")); + } + + private void verifyCodePlacement(boolean hugePages) { + MockRoot root = new MockRoot(""); + SearchNode node = createSearchNode(root, "mynode2", 4, new NodeSpec(7, 5), true, false, hugePages); + node.setHostResource(new HostResource(new Host(node, "mynbode2"))); + node.initService(root.getDeployState()); + assertEquals(hugePages, node.getStartupCommand().contains("VESPA_LOAD_CODE_AS_HUGEPAGES=")); + } + + @Test + public void requireThatCodePageTypeCanBeControlled() { + verifyCodePlacement(true); + verifyCodePlacement(false); + } + + private MockRoot createRoot(ModelContext.Properties properties) { + return new MockRoot("", new DeployState.Builder().properties(properties).build()); + } + + private TranslogserverConfig getTlsConfig(ModelContext.Properties properties, Boolean useFsync) { + MockRoot root = createRoot(properties); + SearchNode node = createSearchNode(root); + prepare(root, node, useFsync); + TranslogserverConfig.Builder tlsBuilder = new TranslogserverConfig.Builder(); + node.getConfig(tlsBuilder); + return tlsBuilder.build(); + } + +} -- cgit v1.2.3