diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/DataTier.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/DataTier.java index 0fa2d5762b908..efe34f777b937 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/DataTier.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/DataTier.java @@ -191,7 +191,11 @@ public static boolean isColdNode(DiscoveryNode discoveryNode) { } public static boolean isFrozenNode(DiscoveryNode discoveryNode) { - return discoveryNode.getRoles().contains(DATA_FROZEN_NODE_ROLE) || discoveryNode.getRoles().contains(DiscoveryNodeRole.DATA_ROLE); + return isFrozenNode(discoveryNode.getRoles()); + } + + public static boolean isFrozenNode(final Set roles) { + return roles.contains(DATA_FROZEN_NODE_ROLE) || roles.contains(DiscoveryNodeRole.DATA_ROLE); } /** diff --git a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/cache/FrozenCacheService.java b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/cache/FrozenCacheService.java index 6366ba49f2726..b1ebbaa5cdf1d 100644 --- a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/cache/FrozenCacheService.java +++ b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/cache/FrozenCacheService.java @@ -13,11 +13,15 @@ import org.elasticsearch.Assertions; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.StepListener; +import org.elasticsearch.cluster.node.DiscoveryNodeRole; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.lease.Releasable; import org.elasticsearch.common.lease.Releasables; +import org.elasticsearch.common.logging.DeprecationCategory; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -30,13 +34,18 @@ import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.store.cache.CacheKey; import org.elasticsearch.index.store.cache.SparseFileTracker; +import org.elasticsearch.node.NodeRoleSettings; import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.xpack.core.DataTier; import java.io.IOException; import java.io.UncheckedIOException; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; @@ -45,6 +54,7 @@ import java.util.function.Consumer; import java.util.function.LongSupplier; import java.util.function.Predicate; +import java.util.stream.Collectors; import static org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshotsUtils.toIntBytes; @@ -67,9 +77,45 @@ public class FrozenCacheService implements Releasable { Setting.Property.NodeScope ); - public static final Setting SNAPSHOT_CACHE_SIZE_SETTING = Setting.byteSizeSetting( + public static final Setting SNAPSHOT_CACHE_SIZE_SETTING = new Setting<>( SHARED_CACHE_SETTINGS_PREFIX + "size", - ByteSizeValue.ZERO, + ByteSizeValue.ZERO.getStringRep(), + s -> ByteSizeValue.parseBytesSizeValue(s, SHARED_CACHE_SETTINGS_PREFIX + "size"), + new Setting.Validator() { + + @Override + public void validate(final ByteSizeValue value) { + + } + + @Override + public void validate(final ByteSizeValue value, final Map, Object> settings) { + if (value.getBytes() == -1) { + throw new SettingsException("setting [{}] must be non-negative", SHARED_CACHE_SETTINGS_PREFIX + "size"); + } + if (value.getBytes() > 0) { + @SuppressWarnings("unchecked") + final List roles = (List) settings.get(NodeRoleSettings.NODE_ROLES_SETTING); + if (DataTier.isFrozenNode(Set.of(roles.toArray(DiscoveryNodeRole[]::new))) == false) { + deprecationLogger.deprecate( + DeprecationCategory.SETTINGS, + "shared_cache", + "setting [{}] to be positive [{}] on node without the data_frozen role is deprecated, roles are [{}]", + SHARED_CACHE_SETTINGS_PREFIX + "size", + value.getStringRep(), + roles.stream().map(DiscoveryNodeRole::roleName).collect(Collectors.joining(",")) + ); + } + } + } + + @Override + public Iterator> settings() { + final List> settings = List.of(NodeRoleSettings.NODE_ROLES_SETTING); + return settings.iterator(); + } + + }, Setting.Property.NodeScope ); @@ -105,6 +151,7 @@ public class FrozenCacheService implements Releasable { ); private static final Logger logger = LogManager.getLogger(FrozenCacheService.class); + private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(FrozenCacheService.class); private final ConcurrentHashMap> keyMapping; diff --git a/x-pack/plugin/searchable-snapshots/src/main/plugin-metadata/plugin-security.codebases b/x-pack/plugin/searchable-snapshots/src/main/plugin-metadata/plugin-security.codebases new file mode 100644 index 0000000000000..3e2c5e5dca726 --- /dev/null +++ b/x-pack/plugin/searchable-snapshots/src/main/plugin-metadata/plugin-security.codebases @@ -0,0 +1 @@ +preallocate: org.elasticsearch.xpack.searchablesnapshots.preallocate.Preallocate diff --git a/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/cache/FrozenCacheServiceTests.java b/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/cache/FrozenCacheServiceTests.java index 769b924a24238..499b0cf4fcef9 100644 --- a/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/cache/FrozenCacheServiceTests.java +++ b/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/cache/FrozenCacheServiceTests.java @@ -8,18 +8,22 @@ package org.elasticsearch.xpack.searchablesnapshots.cache; import org.elasticsearch.cluster.coordination.DeterministicTaskQueue; +import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.env.TestEnvironment; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.store.cache.CacheKey; +import org.elasticsearch.node.NodeRoleSettings; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.xpack.core.DataTier; import org.elasticsearch.xpack.searchablesnapshots.cache.FrozenCacheService.CacheFileRegion; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Set; import static org.elasticsearch.node.Node.NODE_NAME_SETTING; @@ -192,6 +196,23 @@ public void testDecay() throws IOException { } } + public void testCacheSizeDeprecatedOnNonFrozenNodes() { + DiscoveryNode.setAdditionalRoles( + Set.of(DataTier.DATA_HOT_NODE_ROLE, DataTier.DATA_WARM_NODE_ROLE, DataTier.DATA_COLD_NODE_ROLE, DataTier.DATA_FROZEN_NODE_ROLE) + ); + final Settings settings = Settings.builder() + .put(FrozenCacheService.SNAPSHOT_CACHE_SIZE_SETTING.getKey(), "500b") + .put(FrozenCacheService.SNAPSHOT_CACHE_REGION_SIZE_SETTING.getKey(), "100b") + .putList(NodeRoleSettings.NODE_ROLES_SETTING.getKey(), DataTier.DATA_HOT_NODE_ROLE.roleName()) + .build(); + FrozenCacheService.SNAPSHOT_CACHE_SIZE_SETTING.get(settings); + assertWarnings( + "setting [" + + FrozenCacheService.SNAPSHOT_CACHE_SIZE_SETTING.getKey() + + "] to be positive [500b] on node without the data_frozen role is deprecated, roles are [data_hot]" + ); + } + private static CacheKey generateCacheKey() { return new CacheKey( randomAlphaOfLength(10),