diff options
Diffstat (limited to 'config-model/src/main')
13 files changed, 146 insertions, 61 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 ee9af73c554..e645fec5520 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 @@ -75,6 +75,9 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea private boolean asyncApplyBucketDiff = false; private boolean unorderedMergeChaining = false; private List<String> zoneDnsSuffixes = List.of(); + private int maxCompactBuffers = 1; + private boolean failDeploymentWithInvalidJvmOptions = false; + private double tlsSizeFraction = 0.07; @Override public ModelContext.FeatureFlags featureFlags() { return this; } @Override public boolean multitenant() { return multitenant; } @@ -130,6 +133,9 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea @Override public boolean asyncApplyBucketDiff() { return asyncApplyBucketDiff; } @Override public boolean unorderedMergeChaining() { return unorderedMergeChaining; } @Override public List<String> zoneDnsSuffixes() { return zoneDnsSuffixes; } + @Override public int maxCompactBuffers() { return maxCompactBuffers; } + @Override public boolean failDeploymentWithInvalidJvmOptions() { return failDeploymentWithInvalidJvmOptions; } + @Override public double tlsSizeFraction() { return tlsSizeFraction; } public TestProperties maxUnCommittedMemory(int maxUnCommittedMemory) { this.maxUnCommittedMemory = maxUnCommittedMemory; @@ -340,6 +346,21 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea return this; } + public TestProperties maxCompactBuffers(int maxCompactBuffers) { + this.maxCompactBuffers = maxCompactBuffers; + return this; + } + + public TestProperties failDeploymentWithInvalidJvmOptions(boolean fail) { + failDeploymentWithInvalidJvmOptions = fail; + return this; + } + + public TestProperties tlsSizeFraction(double tlsSizeFraction) { + this.tlsSizeFraction = tlsSizeFraction; + return this; + } + public static class Spec implements ConfigServerSpec { private final String hostName; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java index a01d061c21f..cc1369c2470 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java @@ -5,6 +5,7 @@ import com.yahoo.cloud.config.LogforwarderConfig; import com.yahoo.config.model.producer.AbstractConfigProducer; import com.yahoo.vespa.model.AbstractService; import com.yahoo.vespa.model.PortAllocBridge; +import java.util.Optional; public class LogForwarder extends AbstractService implements LogforwarderConfig.Producer { @@ -79,4 +80,13 @@ public class LogForwarder extends AbstractService implements LogforwarderConfig. } } + @Override + public Optional<String> getPreShutdownCommand() { + var builder = new LogforwarderConfig.Builder(); + getConfig(builder); + var cfg = new LogforwarderConfig(builder); + var home = cfg.splunkHome(); + return Optional.of("/usr/bin/env SPLUNK_HOME="+home+" "+home+"/bin/splunk stop"); + } + } 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 8cdeda0e85f..eafc460bfb5 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 @@ -177,7 +177,8 @@ public class ClusterControllerContainer extends Container implements status -> clusterBuilder.documentTypes( typeName, new ReindexingConfig.Clusters.DocumentTypes.Builder() - .readyAtMillis(status.ready().toEpochMilli()))); + .readyAtMillis(status.ready().toEpochMilli()) + .speed(status.speed()))); } builder.clusters(clusterId, clusterBuilder); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java index 2189625ef74..be67cbb9dd6 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java @@ -55,6 +55,7 @@ public class VespaMetricSet { metrics.add(new Metric("slobrok.heartbeats.failed.count")); metrics.add(new Metric("logd.processed.lines.count")); metrics.add(new Metric("worker.connections.max")); + metrics.add(new Metric("endpoint.certificate.expiry.seconds")); // Java (JRT) TLS metrics metrics.add(new Metric("jrt.transport.tls-certificate-verification-failures")); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java index d1dc2b84c8a..841dbb204fd 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java @@ -8,7 +8,6 @@ import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.SystemName; import com.yahoo.vespa.model.VespaModel; -import org.jetbrains.annotations.NotNull; import java.math.BigDecimal; import java.util.Locale; @@ -57,7 +56,6 @@ public class QuotaValidator extends Validator { throwIfBudgetExceeded(maxSpend, budget, systemName); } - @NotNull private Set<ClusterSpec.Id> adminClusterIds(VespaModel model) { return model.allocatedHosts().getHosts().stream() .map(hostSpec -> hostSpec.membership().orElseThrow().cluster()) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java index e8be43fdc96..c4d420f2d44 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java @@ -167,11 +167,17 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat public void setMemoryPercentage(Integer memoryPercentage) { this.memoryPercentage = memoryPercentage; } - /** - * Returns the percentage of host physical memory this application has specified for nodes in this cluster, - * or empty if this is not specified by the application. - */ - public Optional<Integer> getMemoryPercentage() { return Optional.ofNullable(memoryPercentage); } + @Override + public Optional<Integer> getMemoryPercentage() { + if (memoryPercentage != null) { + return Optional.of(memoryPercentage); + } else if (isHostedVespa()) { + return getHostClusterId().isPresent() ? + Optional.of(heapSizePercentageOfTotalNodeMemoryWhenCombinedCluster) : + Optional.of(heapSizePercentageOfTotalNodeMemory); + } + return Optional.empty(); + } /* Create list of endpoints, these will be consumed later by the LBservicesProducer @@ -291,10 +297,6 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat .heapsize(1536); if (getMemoryPercentage().isPresent()) { builder.jvm.heapSizeAsPercentageOfPhysicalMemory(getMemoryPercentage().get()); - } else if (isHostedVespa()) { - builder.jvm.heapSizeAsPercentageOfPhysicalMemory(getHostClusterId().isPresent() ? - heapSizePercentageOfTotalNodeMemoryWhenCombinedCluster : - heapSizePercentageOfTotalNodeMemory); } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java index c4f506d81ba..c73a3b2a676 100755 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java @@ -171,6 +171,9 @@ public abstract class ContainerCluster<CONTAINER extends Container> addCommonVespaBundles(); + // TODO Vespa 8: remove LoggingRequestHandler.Context (replaced by ThreadedHttpRequestHandler.Context) + addSimpleComponent(com.yahoo.container.jdisc.LoggingRequestHandler.Context.class); + addComponent(new StatisticsComponent()); addSimpleComponent(AccessLog.class); addComponent(new DefaultThreadpoolProvider(this, deployState.featureFlags().metricsproxyNumThreads())); @@ -178,7 +181,7 @@ public abstract class ContainerCluster<CONTAINER extends Container> addSimpleComponent("com.yahoo.container.jdisc.metric.MetricConsumerProviderProvider"); addSimpleComponent("com.yahoo.container.jdisc.metric.MetricProvider"); addSimpleComponent("com.yahoo.container.jdisc.metric.MetricUpdater"); - addSimpleComponent(com.yahoo.container.jdisc.LoggingRequestHandler.Context.class); + addSimpleComponent(com.yahoo.container.jdisc.ThreadedHttpRequestHandler.Context.class); addSimpleComponent(com.yahoo.metrics.simple.MetricManager.class.getName(), null, MetricProperties.BUNDLE_SYMBOLIC_NAME); addSimpleComponent(com.yahoo.metrics.simple.jdisc.JdiscMetricsFactory.class.getName(), null, MetricProperties.BUNDLE_SYMBOLIC_NAME); addSimpleComponent("com.yahoo.container.jdisc.state.StateMonitor"); @@ -650,4 +653,9 @@ public abstract class ContainerCluster<CONTAINER extends Container> public boolean getDeferChangesUntilRestart() { return deferChangesUntilRestart; } + /** + * Returns the percentage of host physical memory this application has specified for nodes in this cluster, + * or empty if this is not specified by the application. + */ + public Optional<Integer> getMemoryPercentage() { return Optional.empty(); } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java index 8c31eabfde0..d84884665ef 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java @@ -23,6 +23,7 @@ public class JettyHttpServer extends SimpleComponent implements ServerConfig.Pro private final ContainerCluster<?> cluster; private volatile boolean isHostedVespa; private final List<ConnectorFactory> connectorFactories = new ArrayList<>(); + private final List<String> ignoredUserAgentsList = new ArrayList<>(); public JettyHttpServer(String componentId, ContainerCluster<?> cluster, boolean isHostedVespa) { super(new ComponentModel(componentId, com.yahoo.jdisc.http.server.jetty.JettyHttpServer.class.getName(), null)); @@ -44,10 +45,15 @@ public class JettyHttpServer extends SimpleComponent implements ServerConfig.Pro return Collections.unmodifiableList(connectorFactories); } + public void addIgnoredUserAgent(String userAgent) { + ignoredUserAgentsList.add(userAgent); + } + @Override public void getConfig(ServerConfig.Builder builder) { builder.metric(new ServerConfig.Metric.Builder() .monitoringHandlerPaths(List.of("/state/v1", "/status.html", "/metrics/v2")) + .ignoredUserAgents(ignoredUserAgentsList) .searchHandlerPaths(List.of("/search")) ); if (isHostedVespa) { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 6d184666bdb..c8b2197fc29 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -93,6 +93,7 @@ import org.w3c.dom.Node; import java.net.URI; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -1126,26 +1127,49 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { } } + /** + * Validates JVM GC options and logs a warning if anyone of them has invalid syntax or is an option + * that is unsupported for the running system (e.g. uses CMS options for hosted Vespa, which uses JDK 17) + */ private static class JvmGcOptions { + private static final Pattern validPattern = Pattern.compile("-XX:[+-]*[a-zA-z0-9=]+"); + private static final Pattern invalidCMSPattern = Pattern.compile("-XX:[+-]\\w*CMS[a-zA-z0-9=]+"); + private final DeployState deployState; private final String jvmGcOptions; private final DeployLogger logger; private final boolean isHosted; + private final boolean failDeploymentWithInvalidJvmOptions; public JvmGcOptions(DeployState deployState, String jvmGcOptions) { this.deployState = deployState; this.jvmGcOptions = jvmGcOptions; this.logger = deployState.getDeployLogger(); this.isHosted = deployState.isHosted(); + this.failDeploymentWithInvalidJvmOptions = deployState.featureFlags().failDeploymentWithInvalidJvmOptions(); } private String build() { String options = deployState.getProperties().jvmGCOptions(); if (jvmGcOptions != null) { - log(jvmGcOptions); options = jvmGcOptions; - // TODO: Verify options against lists of allowed and/or disallowed options + String[] optionList = options.split(" "); + List<String> invalidOptions = Arrays.stream(optionList) + .filter(option -> !option.isEmpty()) + .filter(option -> !Pattern.matches(validPattern.pattern(), option)) + .collect(Collectors.toList()); + + if (isHosted) { + // CMS GC options cannot be used in hosted, CMS is unsupported in JDK 17 + invalidOptions.addAll(Arrays.stream(optionList) + .filter(option -> !option.isEmpty()) + .filter(option -> Pattern.matches(invalidCMSPattern.pattern(), option) || + option.equals("-XX:+UseConcMarkSweepGC")) + .collect(Collectors.toList())); + } + + logOrFailInvalidOptions(invalidOptions); } if (options == null || options.isEmpty()) @@ -1154,9 +1178,15 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { return options; } - private void log(String jvmGcOptions) { - if (isHosted) - logger.logApplicationPackage(Level.INFO, "JVM GC options from services.xml: " + jvmGcOptions); + private void logOrFailInvalidOptions(List<String> options) { + if (options.isEmpty()) return; + + Collections.sort(options); + String message = "Invalid JVM GC options from services.xml: " + String.join(",", options); + if (failDeploymentWithInvalidJvmOptions) + throw new IllegalArgumentException(message); + else + logger.logApplicationPackage(WARNING, message); } } 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 13c3c229acb..54d09bacfa9 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 @@ -71,23 +71,24 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> private final double defaultDiskBloatFactor; private final int defaultDocStoreCompressionLevel; private final boolean forwardIssuesToQrs; + private final int defaultMaxCompactBuffers; /** Whether the nodes of this cluster also hosts a container cluster in a hosted system */ - private final boolean combined; + private final double fractionOfMemoryReserved; public static class Builder extends VespaDomBuilder.DomConfigProducerBuilder<ContentSearchCluster> { private final Map<String, NewDocumentType> documentDefinitions; private final Set<NewDocumentType> globallyDistributedDocuments; - private final boolean combined; + private final double fractionOfMemoryReserved; private final ResourceLimits resourceLimits; public Builder(Map<String, NewDocumentType> documentDefinitions, Set<NewDocumentType> globallyDistributedDocuments, - boolean combined, ResourceLimits resourceLimits) { + double fractionOfMemoryReserved, ResourceLimits resourceLimits) { this.documentDefinitions = documentDefinitions; this.globallyDistributedDocuments = globallyDistributedDocuments; - this.combined = combined; + this.fractionOfMemoryReserved = fractionOfMemoryReserved; this.resourceLimits = resourceLimits; } @@ -105,7 +106,7 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> globallyDistributedDocuments, getFlushOnShutdown(flushOnShutdownElem), syncTransactionLog, - combined); + fractionOfMemoryReserved); ModelElement tuning = clusterElem.childByPath("engine.proton.tuning"); if (tuning != null) { @@ -207,7 +208,7 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> Set<NewDocumentType> globallyDistributedDocuments, boolean flushOnShutdown, Boolean syncTransactionLog, - boolean combined) + double fractionOfMemoryReserved) { super(parent, "search"); this.clusterName = clusterName; @@ -216,7 +217,7 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> this.flushOnShutdown = flushOnShutdown; this.syncTransactionLog = syncTransactionLog; - this.combined = combined; + this.fractionOfMemoryReserved = fractionOfMemoryReserved; this.feedSequencerType = convertFeedSequencerType(featureFlags.feedSequencerType()); this.feedTaskLimit = featureFlags.feedTaskLimit(); this.feedMasterTaskLimit = featureFlags.feedMasterTaskLimit(); @@ -225,6 +226,7 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> this.defaultDiskBloatFactor = featureFlags.diskBloatFactor(); this.defaultDocStoreCompressionLevel = featureFlags.docstoreCompressionLevel(); this.forwardIssuesToQrs = featureFlags.forwardIssuesAsErrors(); + this.defaultMaxCompactBuffers = featureFlags.maxCompactBuffers(); } public void setVisibilityDelay(double delay) { @@ -288,7 +290,8 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> Optional<Tuning> tuning = Optional.ofNullable(this.tuning); if (element == null) { searchNode = SearchNode.create(parent, "" + node.getDistributionKey(), node.getDistributionKey(), spec, - clusterName, node, flushOnShutdown, tuning, resourceLimits, parentGroup.isHosted(), combined); + clusterName, node, flushOnShutdown, tuning, resourceLimits, parentGroup.isHosted(), + fractionOfMemoryReserved, deployState.featureFlags().tlsSizeFraction()); searchNode.setHostResource(node.getHostResource()); searchNode.initService(deployState.getDeployLogger()); @@ -296,7 +299,9 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> 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()); + searchNode = new SearchNode.Builder(""+node.getDistributionKey(), spec, clusterName, node, flushOnShutdown, + tuning, resourceLimits, fractionOfMemoryReserved) + .build(deployState, parent, element.getXml()); tls = new TransactionLogServer.Builder(clusterName, syncTransactionLog).build(deployState, searchNode, element.getXml()); } searchNode.setTls(tls); @@ -387,6 +392,7 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> .configid(getConfigId()) .visibilitydelay(visibilityDelay) .global(globalDocType); + ddbB.allocation.max_compact_buffers(defaultMaxCompactBuffers); if (hasIndexingModeStreaming(type)) { hasAnyNonIndexedCluster = true; 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 0c0b2b80d79..628cf6bb4c7 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 @@ -131,7 +131,7 @@ public class ContentCluster extends AbstractConfigProducer<AbstractConfigProduce resourceLimits.getClusterControllerLimits()).build(deployState, c, contentElement.getXml()); c.search = new ContentSearchCluster.Builder(documentDefinitions, globallyDistributedDocuments, - isCombined(getClusterId(contentElement), containers), + fractionOfMemoryReserved(getClusterId(contentElement), containers), resourceLimits.getContentNodeLimits()).build(deployState, c, contentElement.getXml()); c.persistenceFactory = new EngineFactoryBuilder().build(contentElement, c); c.storageNodes = new StorageCluster.Builder().build(deployState, c, w3cContentElement); @@ -240,12 +240,15 @@ public class ContentCluster extends AbstractConfigProducer<AbstractConfigProduce } } - /** Returns whether this hosts one of the given container clusters */ - private boolean isCombined(String clusterId, Collection<ContainerModel> containers) { - return containers.stream() - .map(model -> model.getCluster().getHostClusterId()) - .filter(Optional::isPresent) - .anyMatch(id -> id.get().equals(clusterId)); + /** Returns of memory reserved on a host. Memory is reserved for the jvm if th ecluster is combined */ + private double fractionOfMemoryReserved(String clusterId, Collection<ContainerModel> containers) { + for (ContainerModel containerModel : containers) { + Optional<String> hostClusterId = containerModel.getCluster().getHostClusterId(); + if (hostClusterId.isPresent() && hostClusterId.get().equals(clusterId) && containerModel.getCluster().getMemoryPercentage().isPresent()) { + return containerModel.getCluster().getMemoryPercentage().get() * 0.01; + } + } + return 0.0; } private void setupExperimental(ContentCluster cluster, ModelElement experimental) { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/NodeResourcesTuning.java b/config-model/src/main/java/com/yahoo/vespa/model/search/NodeResourcesTuning.java index 65efcf85b1d..3af0b49de82 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/NodeResourcesTuning.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/search/NodeResourcesTuning.java @@ -3,9 +3,9 @@ package com.yahoo.vespa.model.search; import com.yahoo.config.provision.NodeResources; import com.yahoo.vespa.config.search.core.ProtonConfig; -import com.yahoo.vespa.model.container.ApplicationContainerCluster; import static java.lang.Long.min; +import static java.lang.Long.max; /** * Tuning of proton config for a search node based on the resources on the node. @@ -20,17 +20,20 @@ public class NodeResourcesTuning implements ProtonConfig.Producer { private final static long MEMORY_COST_PER_DOCUMENT_STORE_ONLY = 46L; private final NodeResources resources; private final int threadsPerSearch; - private final boolean combined; + private final double fractionOfMemoryReserved; + private final double tlsSizeFraction; // "Reserve" 0.5GB of memory for other processes running on the content node (config-proxy, metrics-proxy). public static final double reservedMemoryGb = 0.5; public NodeResourcesTuning(NodeResources resources, int threadsPerSearch, - boolean combined) { + double fractionOfMemoryReserved, + double tlsSizeFraction) { this.resources = resources; this.threadsPerSearch = threadsPerSearch; - this.combined = combined; + this.fractionOfMemoryReserved = fractionOfMemoryReserved; + this.tlsSizeFraction = tlsSizeFraction; } @Override @@ -95,8 +98,8 @@ public class NodeResourcesTuning implements ProtonConfig.Producer { } private void tuneFlushStrategyTlsSize(ProtonConfig.Flush.Memory.Builder builder) { - long tlsSizeBytes = (long) ((resources.diskGb() * 0.07) * GB); - tlsSizeBytes = min(tlsSizeBytes, 100 * GB); + long tlsSizeBytes = (long) ((resources.diskGb() * tlsSizeFraction) * GB); + tlsSizeBytes = max(2*GB, min(tlsSizeBytes, 100 * GB)); builder.maxtlssize(tlsSizeBytes); } @@ -122,12 +125,7 @@ public class NodeResourcesTuning implements ProtonConfig.Producer { /** Returns the memory we can expect will be available for the content node processes */ private double usableMemoryGb() { double usableMemoryGb = resources.memoryGb() - reservedMemoryGb; - if ( ! combined) { - return usableMemoryGb; - } - - double fractionTakenByContainer = ApplicationContainerCluster.heapSizePercentageOfTotalNodeMemoryWhenCombinedCluster * 1e-2; - return usableMemoryGb * (1 - fractionTakenByContainer); + return usableMemoryGb * (1 - fractionOfMemoryReserved); } } 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 4b3b464f9e5..31513a273b2 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 @@ -67,9 +67,8 @@ public class SearchNode extends AbstractService implements private AbstractService serviceLayerService; private final Optional<Tuning> tuning; private final Optional<ResourceLimits> resourceLimits; - - /** Whether this search node is co-located with a container node on a hosted system */ - private final boolean combined; + private final double fractionOfMemoryReserved; + private final double tlsSizeFraction; public static class Builder extends VespaDomBuilder.DomConfigProducerBuilder<SearchNode> { @@ -80,11 +79,11 @@ public class SearchNode extends AbstractService implements private final boolean flushOnShutdown; private final Optional<Tuning> tuning; private final Optional<ResourceLimits> resourceLimits; - private boolean combined; + private final double fractionOfMemoryReserved; public Builder(String name, NodeSpec nodeSpec, String clusterName, ContentNode node, boolean flushOnShutdown, Optional<Tuning> tuning, Optional<ResourceLimits> resourceLimits, - boolean combined) { + double fractionOfMemoryReserved) { this.name = name; this.nodeSpec = nodeSpec; this.clusterName = clusterName; @@ -92,13 +91,14 @@ public class SearchNode extends AbstractService implements this.flushOnShutdown = flushOnShutdown; this.tuning = tuning; this.resourceLimits = resourceLimits; - this.combined = combined; + this.fractionOfMemoryReserved = fractionOfMemoryReserved; } @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(), combined); + flushOnShutdown, tuning, resourceLimits, deployState.isHosted(), fractionOfMemoryReserved, + deployState.featureFlags().tlsSizeFraction()); } } @@ -106,16 +106,16 @@ 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> tuning, Optional<ResourceLimits> resourceLimits, boolean isHostedVespa, - boolean combined) { - return new SearchNode(parent, name, distributionKey, nodeSpec, clusterName, serviceLayerService, - flushOnShutdown, tuning, resourceLimits, isHostedVespa, combined); + double fractionOfMemoryReserved, double tlsSizeFraction) { + return new SearchNode(parent, name, distributionKey, nodeSpec, clusterName, serviceLayerService, flushOnShutdown, + tuning, resourceLimits, isHostedVespa, fractionOfMemoryReserved, tlsSizeFraction); } private SearchNode(AbstractConfigProducer parent, String name, int distributionKey, NodeSpec nodeSpec, String clusterName, AbstractService serviceLayerService, boolean flushOnShutdown, Optional<Tuning> tuning, Optional<ResourceLimits> resourceLimits, boolean isHostedVespa, - boolean combined) { - this(parent, name, nodeSpec, clusterName, flushOnShutdown, tuning, resourceLimits, isHostedVespa, combined); + double fractionOfMemoryReserved, double tlsSizeFraction) { + this(parent, name, nodeSpec, clusterName, flushOnShutdown, tuning, resourceLimits, isHostedVespa, fractionOfMemoryReserved, tlsSizeFraction); this.distributionKey = distributionKey; this.serviceLayerService = serviceLayerService; setPropertiesElastic(clusterName, distributionKey); @@ -123,11 +123,12 @@ public class SearchNode extends AbstractService implements private SearchNode(AbstractConfigProducer parent, String name, NodeSpec nodeSpec, String clusterName, boolean flushOnShutdown, Optional<Tuning> tuning, Optional<ResourceLimits> resourceLimits, boolean isHostedVespa, - boolean combined) { + double fractionOfMemoryReserved, double tlsSizeFraction) { super(parent, name); setOmpNumThreads(1); this.isHostedVespa = isHostedVespa; - this.combined = combined; + this.fractionOfMemoryReserved = fractionOfMemoryReserved; + this.tlsSizeFraction = tlsSizeFraction; this.nodeSpec = nodeSpec; this.clusterName = clusterName; this.flushOnShutdown = flushOnShutdown; @@ -281,7 +282,7 @@ public class SearchNode extends AbstractService implements if (nodeResources.isPresent()) { var nodeResourcesTuning = new NodeResourcesTuning(nodeResources.get(), tuning.map(Tuning::threadsPerSearch).orElse(1), - combined); + fractionOfMemoryReserved, tlsSizeFraction); nodeResourcesTuning.getConfig(builder); tuning.ifPresent(t -> t.getConfig(builder)); |