summaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/vespa/model/search/NodeFlavorTuning.java
diff options
context:
space:
mode:
Diffstat (limited to 'config-model/src/main/java/com/yahoo/vespa/model/search/NodeFlavorTuning.java')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/search/NodeFlavorTuning.java129
1 files changed, 129 insertions, 0 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/NodeFlavorTuning.java b/config-model/src/main/java/com/yahoo/vespa/model/search/NodeFlavorTuning.java
new file mode 100644
index 00000000000..0998d583d6c
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/search/NodeFlavorTuning.java
@@ -0,0 +1,129 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.search;
+
+import com.yahoo.config.provision.Flavor;
+import com.yahoo.vespa.config.search.core.ProtonConfig;
+
+import static java.lang.Long.min;
+
+/**
+ * Tuning of proton config for a search node based on the node flavor of that node.
+ *
+ * @author geirst
+ */
+public class NodeFlavorTuning implements ProtonConfig.Producer {
+
+ static long MB = 1024 * 1024;
+ static long GB = MB * 1024;
+ private final Flavor nodeFlavor;
+ private final int redundancy;
+ private final int searchableCopies;
+ private final int threadsPerSearch;
+
+
+ public NodeFlavorTuning(Flavor nodeFlavor, int redundancy, int searchableCopies) {
+ this(nodeFlavor, redundancy, searchableCopies, 1);
+ }
+ public NodeFlavorTuning(Flavor nodeFlavor, int redundancy, int searchableCopies, int threadsPerSearch) {
+ this.nodeFlavor = nodeFlavor;
+ this.redundancy = redundancy;
+ this.searchableCopies = searchableCopies;
+ this.threadsPerSearch = threadsPerSearch;
+ }
+
+ @Override
+ public void getConfig(ProtonConfig.Builder builder) {
+ setHwInfo(builder);
+ tuneDiskWriteSpeed(builder);
+ tuneRequestThreads(builder);
+ tuneDocumentStoreMaxFileSize(builder.summary.log);
+ tuneFlushStrategyMemoryLimits(builder.flush.memory);
+ tuneFlushStrategyTlsSize(builder.flush.memory);
+ tuneSummaryReadIo(builder.summary.read);
+ tuneSummaryCache(builder.summary.cache);
+ tuneSearchReadIo(builder.search.mmap);
+ tuneWriteFilter(builder.writefilter);
+ for (ProtonConfig.Documentdb.Builder dbb : builder.documentdb) {
+ getConfig(dbb);
+ }
+ }
+
+ private void getConfig(ProtonConfig.Documentdb.Builder builder) {
+ ProtonConfig.Documentdb dbCfg = builder.build();
+ if (dbCfg.mode() != ProtonConfig.Documentdb.Mode.Enum.INDEX) {
+ long numDocs = (long)nodeFlavor.getMinMainMemoryAvailableGb()*GB/64L;
+ builder.allocation.initialnumdocs(numDocs/Math.max(searchableCopies, redundancy));
+ }
+ }
+
+ private void tuneSummaryCache(ProtonConfig.Summary.Cache.Builder builder) {
+ long memoryLimitBytes = (long) ((nodeFlavor.getMinMainMemoryAvailableGb() * 0.05) * GB);
+ builder.maxbytes(memoryLimitBytes);
+ }
+
+ private void setHwInfo(ProtonConfig.Builder builder) {
+ builder.hwinfo.disk.shared(nodeFlavor.getType().equals(Flavor.Type.DOCKER_CONTAINER));
+ builder.hwinfo.cpu.cores((int)nodeFlavor.getMinCpuCores());
+ builder.hwinfo.memory.size((long)nodeFlavor.resources().memoryGb() * GB);
+ builder.hwinfo.disk.size((long)nodeFlavor.resources().diskGb() * GB);
+ }
+
+ private void tuneDiskWriteSpeed(ProtonConfig.Builder builder) {
+ if (!nodeFlavor.hasFastDisk()) {
+ builder.hwinfo.disk.writespeed(40);
+ }
+ }
+
+ private void tuneDocumentStoreMaxFileSize(ProtonConfig.Summary.Log.Builder builder) {
+ double memoryGb = nodeFlavor.getMinMainMemoryAvailableGb();
+ long fileSizeBytes = 4 * GB;
+ if (memoryGb <= 12.0) {
+ fileSizeBytes = 256 * MB;
+ } else if (memoryGb < 24.0) {
+ fileSizeBytes = 512 * MB;
+ } else if (memoryGb <= 64.0) {
+ fileSizeBytes = 1 * GB;
+ }
+ builder.maxfilesize(fileSizeBytes);
+ }
+
+ private void tuneFlushStrategyMemoryLimits(ProtonConfig.Flush.Memory.Builder builder) {
+ long memoryLimitBytes = (long) ((nodeFlavor.getMinMainMemoryAvailableGb() / 8) * GB);
+ builder.maxmemory(memoryLimitBytes);
+ builder.each.maxmemory(memoryLimitBytes);
+ }
+
+ private void tuneFlushStrategyTlsSize(ProtonConfig.Flush.Memory.Builder builder) {
+ long tlsSizeBytes = (long) ((nodeFlavor.getMinDiskAvailableGb() * 0.07) * GB);
+ tlsSizeBytes = min(tlsSizeBytes, 100 * GB);
+ builder.maxtlssize(tlsSizeBytes);
+ }
+
+ private void tuneSummaryReadIo(ProtonConfig.Summary.Read.Builder builder) {
+ if (nodeFlavor.hasFastDisk()) {
+ builder.io(ProtonConfig.Summary.Read.Io.DIRECTIO);
+ }
+ }
+
+ private void tuneSearchReadIo(ProtonConfig.Search.Mmap.Builder builder) {
+ if (nodeFlavor.hasFastDisk()) {
+ builder.advise(ProtonConfig.Search.Mmap.Advise.RANDOM);
+ }
+ }
+
+ private void tuneRequestThreads(ProtonConfig.Builder builder) {
+ int numCores = (int)Math.ceil(nodeFlavor.getMinCpuCores());
+ builder.numsearcherthreads(numCores*threadsPerSearch);
+ builder.numsummarythreads(numCores);
+ builder.numthreadspersearch(threadsPerSearch);
+ }
+
+ private void tuneWriteFilter(ProtonConfig.Writefilter.Builder builder) {
+ // "Reserve" 1GB of memory for other processes running on the content node (config-proxy, cluster-controller, metrics-proxy)
+ double reservedMemoryGb = 1;
+ double defaultMemoryLimit = new ProtonConfig.Writefilter(new ProtonConfig.Writefilter.Builder()).memorylimit();
+ double scaledMemoryLimit = ((nodeFlavor.getMinMainMemoryAvailableGb() - reservedMemoryGb) * defaultMemoryLimit) / nodeFlavor.getMinMainMemoryAvailableGb();
+ builder.memorylimit(scaledMemoryLimit);
+ }
+
+}