|
38 | 38 | import org.opensearch.Build;
|
39 | 39 | import org.opensearch.ExceptionsHelper;
|
40 | 40 | import org.opensearch.OpenSearchException;
|
| 41 | +import org.opensearch.OpenSearchParseException; |
41 | 42 | import org.opensearch.OpenSearchTimeoutException;
|
42 | 43 | import org.opensearch.Version;
|
43 | 44 | import org.opensearch.action.ActionModule;
|
|
108 | 109 | import org.opensearch.common.settings.Settings;
|
109 | 110 | import org.opensearch.common.settings.SettingsException;
|
110 | 111 | import org.opensearch.common.settings.SettingsModule;
|
| 112 | +import org.opensearch.common.unit.RatioValue; |
111 | 113 | import org.opensearch.common.unit.TimeValue;
|
112 | 114 | import org.opensearch.common.util.BigArrays;
|
113 | 115 | import org.opensearch.common.util.FeatureFlags;
|
|
176 | 178 | import org.opensearch.ingest.IngestService;
|
177 | 179 | import org.opensearch.monitor.MonitorService;
|
178 | 180 | import org.opensearch.monitor.fs.FsHealthService;
|
179 |
| -import org.opensearch.monitor.fs.FsInfo; |
180 | 181 | import org.opensearch.monitor.fs.FsProbe;
|
181 | 182 | import org.opensearch.monitor.jvm.JvmInfo;
|
182 | 183 | import org.opensearch.node.remotestore.RemoteStoreNodeService;
|
@@ -372,9 +373,12 @@ public class Node implements Closeable {
|
372 | 373 | }
|
373 | 374 | }, Setting.Property.NodeScope);
|
374 | 375 |
|
375 |
| - public static final Setting<ByteSizeValue> NODE_SEARCH_CACHE_SIZE_SETTING = Setting.byteSizeSetting( |
| 376 | + private static final String ZERO = "0"; |
| 377 | + |
| 378 | + public static final Setting<String> NODE_SEARCH_CACHE_SIZE_SETTING = new Setting<>( |
376 | 379 | "node.search.cache.size",
|
377 |
| - ByteSizeValue.ZERO, |
| 380 | + s -> (FeatureFlags.isEnabled(FeatureFlags.TIERED_REMOTE_INDEX_SETTING) || DiscoveryNode.isDedicatedSearchNode(s)) ? "80%" : ZERO, |
| 381 | + Node::validateFileCacheSize, |
378 | 382 | Property.NodeScope
|
379 | 383 | );
|
380 | 384 |
|
@@ -2002,43 +2006,59 @@ DiscoveryNode getNode() {
|
2002 | 2006 | * Initializes the search cache with a defined capacity.
|
2003 | 2007 | * The capacity of the cache is based on user configuration for {@link Node#NODE_SEARCH_CACHE_SIZE_SETTING}.
|
2004 | 2008 | * If the user doesn't configure the cache size, it fails if the node is a data + search node.
|
2005 |
| - * Else it configures the size to 80% of available capacity for a dedicated search node, if not explicitly defined. |
| 2009 | + * Else it configures the size to 80% of total capacity for a dedicated search node, if not explicitly defined. |
2006 | 2010 | */
|
2007 | 2011 | private void initializeFileCache(Settings settings, CircuitBreaker circuitBreaker) throws IOException {
|
2008 | 2012 | boolean isWritableRemoteIndexEnabled = FeatureFlags.isEnabled(FeatureFlags.TIERED_REMOTE_INDEX_SETTING);
|
2009 |
| - if (DiscoveryNode.isSearchNode(settings) || isWritableRemoteIndexEnabled) { |
2010 |
| - NodeEnvironment.NodePath fileCacheNodePath = nodeEnvironment.fileCacheNodePath(); |
2011 |
| - long capacity = NODE_SEARCH_CACHE_SIZE_SETTING.get(settings).getBytes(); |
2012 |
| - FsInfo.Path info = ExceptionsHelper.catchAsRuntimeException(() -> FsProbe.getFSInfo(fileCacheNodePath)); |
2013 |
| - long availableCapacity = info.getAvailable().getBytes(); |
2014 |
| - |
2015 |
| - // Initialize default values for cache if NODE_SEARCH_CACHE_SIZE_SETTING is not set. |
2016 |
| - if (capacity == 0) { |
2017 |
| - // If node is not a dedicated search node without configuration, prevent cache initialization |
2018 |
| - if (!isWritableRemoteIndexEnabled |
2019 |
| - && DiscoveryNode.getRolesFromSettings(settings) |
2020 |
| - .stream() |
2021 |
| - .anyMatch(role -> !DiscoveryNodeRole.SEARCH_ROLE.equals(role))) { |
2022 |
| - throw new SettingsException( |
2023 |
| - "Unable to initialize the " |
2024 |
| - + DiscoveryNodeRole.SEARCH_ROLE.roleName() |
2025 |
| - + "-" |
2026 |
| - + DiscoveryNodeRole.DATA_ROLE.roleName() |
2027 |
| - + " node: Missing value for configuration " |
2028 |
| - + NODE_SEARCH_CACHE_SIZE_SETTING.getKey() |
2029 |
| - ); |
2030 |
| - } else { |
2031 |
| - capacity = 80 * availableCapacity / 100; |
2032 |
| - } |
| 2013 | + if (DiscoveryNode.isSearchNode(settings) == false && isWritableRemoteIndexEnabled == false) { |
| 2014 | + return; |
| 2015 | + } |
| 2016 | + |
| 2017 | + String capacityRaw = NODE_SEARCH_CACHE_SIZE_SETTING.get(settings); |
| 2018 | + logger.info("cache size [{}]", capacityRaw); |
| 2019 | + if (capacityRaw.equals(ZERO)) { |
| 2020 | + throw new SettingsException( |
| 2021 | + "Unable to initialize the " |
| 2022 | + + DiscoveryNodeRole.SEARCH_ROLE.roleName() |
| 2023 | + + "-" |
| 2024 | + + DiscoveryNodeRole.DATA_ROLE.roleName() |
| 2025 | + + " node: Missing value for configuration " |
| 2026 | + + NODE_SEARCH_CACHE_SIZE_SETTING.getKey() |
| 2027 | + ); |
| 2028 | + } |
| 2029 | + |
| 2030 | + NodeEnvironment.NodePath fileCacheNodePath = nodeEnvironment.fileCacheNodePath(); |
| 2031 | + long totalSpace = ExceptionsHelper.catchAsRuntimeException(() -> FsProbe.getTotalSize(fileCacheNodePath)); |
| 2032 | + long capacity = calculateFileCacheSize(capacityRaw, totalSpace); |
| 2033 | + if (capacity <= 0 || totalSpace <= capacity) { |
| 2034 | + throw new SettingsException("Cache size must be larger than zero and less than total capacity"); |
| 2035 | + } |
| 2036 | + |
| 2037 | + this.fileCache = FileCacheFactory.createConcurrentLRUFileCache(capacity, circuitBreaker); |
| 2038 | + fileCacheNodePath.fileCacheReservedSize = new ByteSizeValue(this.fileCache.capacity(), ByteSizeUnit.BYTES); |
| 2039 | + List<Path> fileCacheDataPaths = collectFileCacheDataPath(fileCacheNodePath); |
| 2040 | + this.fileCache.restoreFromDirectory(fileCacheDataPaths); |
| 2041 | + } |
| 2042 | + |
| 2043 | + private static long calculateFileCacheSize(String capacityRaw, long totalSpace) { |
| 2044 | + try { |
| 2045 | + RatioValue ratioValue = RatioValue.parseRatioValue(capacityRaw); |
| 2046 | + return Math.round(totalSpace * ratioValue.getAsRatio()); |
| 2047 | + } catch (OpenSearchParseException e) { |
| 2048 | + try { |
| 2049 | + return ByteSizeValue.parseBytesSizeValue(capacityRaw, NODE_SEARCH_CACHE_SIZE_SETTING.getKey()).getBytes(); |
| 2050 | + } catch (OpenSearchParseException ex) { |
| 2051 | + ex.addSuppressed(e); |
| 2052 | + throw ex; |
2033 | 2053 | }
|
2034 |
| - capacity = Math.min(capacity, availableCapacity); |
2035 |
| - fileCacheNodePath.fileCacheReservedSize = new ByteSizeValue(capacity, ByteSizeUnit.BYTES); |
2036 |
| - this.fileCache = FileCacheFactory.createConcurrentLRUFileCache(capacity, circuitBreaker); |
2037 |
| - List<Path> fileCacheDataPaths = collectFileCacheDataPath(fileCacheNodePath); |
2038 |
| - this.fileCache.restoreFromDirectory(fileCacheDataPaths); |
2039 | 2054 | }
|
2040 | 2055 | }
|
2041 | 2056 |
|
| 2057 | + private static String validateFileCacheSize(String capacityRaw) { |
| 2058 | + calculateFileCacheSize(capacityRaw, 0L); |
| 2059 | + return capacityRaw; |
| 2060 | + } |
| 2061 | + |
2042 | 2062 | /**
|
2043 | 2063 | * Returns the {@link FileCache} instance for remote search node
|
2044 | 2064 | * Note: Visible for testing
|
|
0 commit comments