Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Use S3CrtClient for higher throughput while uploading files to S3 ([#18800](https://github.com/opensearch-project/OpenSearch/pull/18800))
- [Rule-based Auto-tagging] bug fix on Update Rule API with multiple attributes ([#19497](https://github.com/opensearch-project/OpenSearch/pull/19497))
- Add a dynamic setting to change skip_cache_factor and min_frequency for querycache ([#18351](https://github.com/opensearch-project/OpenSearch/issues/18351))
- Adding support for Composite Remote Repository. ([#19240](https://github.com/opensearch-project/OpenSearch/pull/19240))
- Add overload constructor for Translog to accept Channel Factory as a parameter ([#18918](https://github.com/opensearch-project/OpenSearch/pull/18918))
- Add subdirectory-aware store module with recovery support ([#19132](https://github.com/opensearch-project/OpenSearch/pull/19132))
- [Rule-based Auto-tagging] Modify get rule api to suit nested attributes ([#19429](https://github.com/opensearch-project/OpenSearch/pull/19429))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ public Iterator<Setting<?>> settings() {
);

public static final String SETTING_REMOTE_STORE_ENABLED = "index.remote_store.enabled";
public static final String SETTING_REMOTE_STORE_SSE_ENABLED = "index.remote_store.sse.enabled";
public static final String SETTING_INDEX_APPEND_ONLY_ENABLED = "index.append_only.enabled";

public static final String SETTING_REMOTE_SEGMENT_STORE_REPOSITORY = "index.remote_store.segment.repository";
Expand Down Expand Up @@ -414,6 +415,38 @@ public Iterator<Setting<?>> settings() {
Property.Dynamic
);

/**
* Used to specify if the index data should be persisted in the remote store.
*/
public static final Setting<Boolean> INDEX_REMOTE_STORE_SSE_ENABLED_SETTING = Setting.boolSetting(
SETTING_REMOTE_STORE_SSE_ENABLED,
false,
new Setting.Validator<>() {

@Override
public void validate(final Boolean value) {}

@Override
public void validate(final Boolean value, final Map<Setting<?>, Object> settings) {
final Boolean isRemoteStoreEnabled = (Boolean) settings.get(INDEX_REMOTE_STORE_ENABLED_SETTING);
if (!isRemoteStoreEnabled && value) {
throw new IllegalArgumentException(
"Server Side Encryption can be enabled when " + INDEX_REMOTE_STORE_ENABLED_SETTING.getKey() + " is enabled. "
);
}
}

@Override
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(INDEX_REMOTE_STORE_ENABLED_SETTING);
return settings.iterator();
}
},
Property.IndexScope,
Property.PrivateIndex,
Property.Dynamic
);

/**
* Used to specify if the index data should be persisted in the remote store.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ IndexMetadata buildAndValidateTemporaryIndexMetadata(
tmpImdBuilder.setRoutingNumShards(routingNumShards);
tmpImdBuilder.settings(aggregatedIndexSettings);
tmpImdBuilder.system(isSystem);
addRemoteStoreCustomMetadata(tmpImdBuilder, true);
addRemoteStoreCustomMetadata(tmpImdBuilder, aggregatedIndexSettings, true);

if (request.context() != null) {
tmpImdBuilder.context(request.context());
Expand All @@ -661,7 +661,7 @@ IndexMetadata buildAndValidateTemporaryIndexMetadata(
* @param tmpImdBuilder index metadata builder.
* @param assertNullOldType flag to verify that the old remote store path type is null
*/
public void addRemoteStoreCustomMetadata(IndexMetadata.Builder tmpImdBuilder, boolean assertNullOldType) {
public void addRemoteStoreCustomMetadata(IndexMetadata.Builder tmpImdBuilder, Settings idxSettings, boolean assertNullOldType) {
if (remoteStoreCustomMetadataResolver == null) {
return;
}
Expand All @@ -673,7 +673,7 @@ public void addRemoteStoreCustomMetadata(IndexMetadata.Builder tmpImdBuilder, bo
Map<String, String> remoteCustomData = new HashMap<>();

// Determine if the ckp would be stored as translog metadata
boolean isTranslogMetadataEnabled = remoteStoreCustomMetadataResolver.isTranslogMetadataEnabled();
boolean isTranslogMetadataEnabled = remoteStoreCustomMetadataResolver.isTranslogMetadataEnabled(idxSettings);
remoteCustomData.put(IndexMetadata.TRANSLOG_METADATA_KEY, Boolean.toString(isTranslogMetadataEnabled));

// Determine the path type for use using the remoteStorePathResolver.
Expand Down Expand Up @@ -1056,7 +1056,7 @@ static Settings aggregateIndexSettings(
indexSettingsBuilder.put(SETTING_INDEX_UUID, UUIDs.randomBase64UUID());

updateReplicationStrategy(indexSettingsBuilder, request.settings(), settings, combinedTemplateSettings, clusterSettings);
updateRemoteStoreSettings(indexSettingsBuilder, currentState, clusterSettings, settings, request.index());
updateRemoteStoreSettings(indexSettingsBuilder, currentState, clusterSettings, settings, request.index(), false);

if (sourceMetadata != null) {
assert request.resizeType() != null;
Expand Down Expand Up @@ -1149,6 +1149,25 @@ public static void updateReplicationStrategy(
settingsBuilder.put(SETTING_REPLICATION_TYPE, indexReplicationType);
}

public static void updateRemoteStoreSettings(
Settings.Builder settingsBuilder,
ClusterState clusterState,
ClusterSettings clusterSettings,
Settings nodeSettings,
String indexName,
IndexMetadata indexMetadata
) {
if ((isRemoteDataAttributePresent(nodeSettings)
&& clusterSettings.get(REMOTE_STORE_COMPATIBILITY_MODE_SETTING).equals(RemoteStoreNodeService.CompatibilityMode.STRICT))
|| isMigratingToRemoteStore(clusterSettings)) {
boolean sseEnabledIndex = IndexMetadata.INDEX_REMOTE_STORE_SSE_ENABLED_SETTING.get(indexMetadata.getSettings());
if (sseEnabledIndex) {
settingsBuilder.put(IndexMetadata.SETTING_REMOTE_STORE_SSE_ENABLED, true);
}
updateRemoteStoreSettings(settingsBuilder, clusterState, clusterSettings, nodeSettings, indexName, true);
}
}

/**
* Updates index settings to enable remote store by default based on node attributes
* @param settingsBuilder index settings builder to be updated with relevant settings
Expand All @@ -1162,7 +1181,8 @@ public static void updateRemoteStoreSettings(
ClusterState clusterState,
ClusterSettings clusterSettings,
Settings nodeSettings,
String indexName
String indexName,
boolean isRestoreFromSnapshot
) {
if ((isRemoteDataAttributePresent(nodeSettings)
&& clusterSettings.get(REMOTE_STORE_COMPATIBILITY_MODE_SETTING).equals(RemoteStoreNodeService.CompatibilityMode.STRICT))
Expand All @@ -1176,9 +1196,20 @@ public static void updateRemoteStoreSettings(
.filter(DiscoveryNode::isRemoteStoreNode)
.findFirst();

if (!isRestoreFromSnapshot && RemoteStoreNodeAttribute.isRemoteStoreServerSideEncryptionEnabled()) {
settingsBuilder.put(IndexMetadata.SETTING_REMOTE_STORE_SSE_ENABLED, true);
}

if (remoteNode.isPresent()) {
translogRepo = RemoteStoreNodeAttribute.getTranslogRepoName(remoteNode.get().getAttributes());
segmentRepo = RemoteStoreNodeAttribute.getSegmentRepoName(remoteNode.get().getAttributes());
Map<String, Object> indexSettings = settingsBuilder.keys()
.stream()
.collect(Collectors.toMap(key -> key, settingsBuilder::get));

Settings.Builder currentSettingsBuilder = Settings.builder();
Settings currentIndexSettings = currentSettingsBuilder.loadFromMap(indexSettings).build();

translogRepo = RemoteStoreNodeAttribute.getRemoteStoreTranslogRepo(currentIndexSettings);
segmentRepo = RemoteStoreNodeAttribute.getRemoteStoreSegmentRepo(currentIndexSettings);
if (segmentRepo != null) {
settingsBuilder.put(SETTING_REMOTE_STORE_ENABLED, true).put(SETTING_REMOTE_SEGMENT_STORE_REPOSITORY, segmentRepo);
if (translogRepo != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings {

// Settings for remote store enablement
IndexMetadata.INDEX_REMOTE_STORE_ENABLED_SETTING,
IndexMetadata.INDEX_REMOTE_STORE_SSE_ENABLED_SETTING,
IndexMetadata.INDEX_REMOTE_SEGMENT_STORE_REPOSITORY_SETTING,
IndexMetadata.INDEX_REMOTE_TRANSLOG_REPOSITORY_SETTING,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ public synchronized IndexShard createShard(
}

remoteDirectory = ((RemoteSegmentStoreDirectoryFactory) remoteDirectoryFactory).newDirectory(
RemoteStoreNodeAttribute.getRemoteStoreSegmentRepo(this.indexSettings.getNodeSettings()),
RemoteStoreNodeAttribute.getRemoteStoreSegmentRepo(this.indexSettings.getSettings()),
this.indexSettings.getUUID(),
shardId,
this.indexSettings.getRemoteStorePathStrategy(),
Expand Down
17 changes: 17 additions & 0 deletions server/src/main/java/org/opensearch/index/IndexSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,8 @@ private void setRetentionLeaseMillis(final TimeValue retentionLease) {
*/
private final boolean isCompositeIndex;

private boolean isRemoteStoreSSEnabled;

/**
* Denotes whether search via star tree index is enabled for this index
*/
Expand Down Expand Up @@ -1035,6 +1037,7 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
numberOfShards = settings.getAsInt(IndexMetadata.SETTING_NUMBER_OF_SHARDS, null);
replicationType = IndexMetadata.INDEX_REPLICATION_TYPE_SETTING.get(settings);
isRemoteStoreEnabled = settings.getAsBoolean(IndexMetadata.SETTING_REMOTE_STORE_ENABLED, false);
isRemoteStoreSSEnabled = settings.getAsBoolean(IndexMetadata.SETTING_REMOTE_STORE_SSE_ENABLED, false);

isWarmIndex = settings.getAsBoolean(IndexModule.IS_WARM_INDEX_SETTING.getKey(), false);

Expand Down Expand Up @@ -1239,6 +1242,9 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
);
scopedSettings.addSettingsUpdateConsumer(ALLOW_DERIVED_FIELDS, this::setAllowDerivedField);
scopedSettings.addSettingsUpdateConsumer(IndexMetadata.INDEX_REMOTE_STORE_ENABLED_SETTING, this::setRemoteStoreEnabled);

scopedSettings.addSettingsUpdateConsumer(IndexMetadata.INDEX_REMOTE_STORE_SSE_ENABLED_SETTING, this::setRemoteStoreSseEnabled);

scopedSettings.addSettingsUpdateConsumer(
IndexMetadata.INDEX_REMOTE_SEGMENT_STORE_REPOSITORY_SETTING,
this::setRemoteStoreRepository
Expand Down Expand Up @@ -1427,6 +1433,13 @@ public boolean isRemoteStoreEnabled() {
return isRemoteStoreEnabled;
}

/**
* Returns if remote store is enabled for this index.
*/
public boolean isRemoteStoreSSEnabled() {
return isRemoteStoreSSEnabled;
}

public boolean isAssignedOnRemoteNode() {
return assignedOnRemoteNode;
}
Expand Down Expand Up @@ -2137,6 +2150,10 @@ public void setRemoteStoreEnabled(boolean isRemoteStoreEnabled) {
this.isRemoteStoreEnabled = isRemoteStoreEnabled;
}

public void setRemoteStoreSseEnabled(boolean sseEnabled) {
this.isRemoteStoreSSEnabled = sseEnabled;
}

public void setRemoteStoreRepository(String remoteStoreRepository) {
this.remoteStoreRepository = remoteStoreRepository;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,15 +234,15 @@ public void start() {
return;
}

translogRepository = (BlobStoreRepository) validateAndGetRepository(RemoteStoreNodeAttribute.getRemoteStoreTranslogRepo(settings));
segmentRepository = (BlobStoreRepository) validateAndGetRepository(RemoteStoreNodeAttribute.getRemoteStoreSegmentRepo(settings));
translogRepository = (BlobStoreRepository) validateAndGetRepository(RemoteStoreNodeAttribute.getRemoteStoreTranslogRepo(false));
segmentRepository = (BlobStoreRepository) validateAndGetRepository(RemoteStoreNodeAttribute.getRemoteStoreSegmentRepo(false));
}

private boolean isTranslogSegmentRepoSame() {
// TODO - The current comparison checks the repository name. But it is also possible that the repository are same
// by attributes, but different by name. We need to handle this.
String translogRepoName = RemoteStoreNodeAttribute.getRemoteStoreTranslogRepo(settings);
String segmentRepoName = RemoteStoreNodeAttribute.getRemoteStoreSegmentRepo(settings);
String translogRepoName = RemoteStoreNodeAttribute.getRemoteStoreTranslogRepo(false);
String segmentRepoName = RemoteStoreNodeAttribute.getRemoteStoreSegmentRepo(false);
return Objects.equals(translogRepoName, segmentRepoName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import static org.opensearch.cluster.metadata.IndexMetadata.SETTING_REMOTE_TRANSLOG_STORE_REPOSITORY;
import static org.opensearch.cluster.metadata.IndexMetadata.SETTING_REPLICATION_TYPE;
import static org.opensearch.index.remote.RemoteStoreUtils.determineRemoteStoreCustomMetadataDuringMigration;
import static org.opensearch.index.remote.RemoteStoreUtils.getRemoteStoreRepoName;

/**
* Utils for checking and mutating cluster state during remote migration
Expand Down Expand Up @@ -72,13 +71,12 @@ public void maybeAddRemoteIndexSettings(IndexMetadata.Builder indexMetadataBuild
"Index {} does not have remote store based index settings but all primary shards and STARTED replica shards have moved to remote enabled nodes. Applying remote store settings to the index",
index
);
Map<String, String> remoteRepoNames = getRemoteStoreRepoName(discoveryNodes);
String segmentRepoName = RemoteStoreNodeAttribute.getSegmentRepoName(remoteRepoNames);
String tlogRepoName = RemoteStoreNodeAttribute.getTranslogRepoName(remoteRepoNames);
String segmentRepoName = RemoteStoreNodeAttribute.getRemoteStoreSegmentRepo(currentIndexSettings);
String translogRepoName = RemoteStoreNodeAttribute.getRemoteStoreTranslogRepo(currentIndexSettings);

assert Objects.nonNull(segmentRepoName) && Objects.nonNull(tlogRepoName) : "Remote repo names cannot be null";
assert Objects.nonNull(segmentRepoName) && Objects.nonNull(translogRepoName) : "Remote repo names cannot be null";
Settings.Builder indexSettingsBuilder = Settings.builder().put(currentIndexSettings);
updateRemoteStoreSettings(indexSettingsBuilder, segmentRepoName, tlogRepoName);
updateRemoteStoreSettings(indexSettingsBuilder, segmentRepoName, translogRepoName);
indexMetadataBuilder.settings(indexSettingsBuilder);
indexMetadataBuilder.settingsVersion(1 + indexMetadata.getVersion());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ public RemoteStorePathStrategy getPathStrategy() {
return new RemoteStorePathStrategy(pathType, pathHashAlgorithm);
}

public boolean isTranslogMetadataEnabled() {
public boolean isTranslogMetadataEnabled(Settings idxSettings) {
Repository repository;
try {
repository = repositoriesServiceSupplier.get().repository(getRemoteStoreTranslogRepo(settings));
repository = repositoriesServiceSupplier.get().repository(getRemoteStoreTranslogRepo(idxSettings));
} catch (RepositoryMissingException ex) {
throw new IllegalArgumentException("Repository should be created before creating index with remote_store enabled setting", ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ private static BiFunction<IndexSettings, ShardRouting, TranslogFactory> getTrans
return new RemoteBlobStoreInternalTranslogFactory(
repositoriesServiceSupplier,
threadPool,
RemoteStoreNodeAttribute.getRemoteStoreTranslogRepo(indexSettings.getNodeSettings()),
RemoteStoreNodeAttribute.getRemoteStoreTranslogRepo(false),
remoteStoreStatsTrackerFactory.getRemoteTranslogTransferTracker(shardRouting.shardId()),
remoteStoreSettings
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.node.remotestore;

import org.opensearch.cluster.metadata.RepositoryMetadata;

import java.util.HashMap;
import java.util.Map;

/**
* Composite Repository for the ServerSideEncryption support.
*/
public class CompositeRemoteRepository {

private final Map<RemoteStoreRepositoryType, Map<CompositeRepositoryEncryptionType, RepositoryMetadata>> repositoryEncryptionTypeMap;

public CompositeRemoteRepository() {
repositoryEncryptionTypeMap = new HashMap<>();
}

public void registerCompositeRepository(
final RemoteStoreRepositoryType repositoryType,
final CompositeRepositoryEncryptionType type,
final RepositoryMetadata metadata
) {
Map<CompositeRepositoryEncryptionType, RepositoryMetadata> encryptionTypeMap = repositoryEncryptionTypeMap.get(repositoryType);
if (encryptionTypeMap == null) {
encryptionTypeMap = new HashMap<>();
}
encryptionTypeMap.put(type, metadata);

repositoryEncryptionTypeMap.put(repositoryType, encryptionTypeMap);
}

public RepositoryMetadata getRepository(RemoteStoreRepositoryType repositoryType, CompositeRepositoryEncryptionType encryptionType) {
Map<CompositeRepositoryEncryptionType, RepositoryMetadata> encTypeRepoMap = repositoryEncryptionTypeMap.get(repositoryType);
return encTypeRepoMap == null ? null : encTypeRepoMap.get(encryptionType);
}

public boolean isServerSideEncryptionEnabled() {
return repositoryEncryptionTypeMap.get(RemoteStoreRepositoryType.SEGMENT) != null
&& repositoryEncryptionTypeMap.get(RemoteStoreRepositoryType.SEGMENT).containsKey(CompositeRepositoryEncryptionType.SERVER);
}

/**
* Enum for Remote store repo types
*/
public enum RemoteStoreRepositoryType {
SEGMENT,
TRANSLOG
}

/**
* Enum for composite repo types
*/
public enum CompositeRepositoryEncryptionType {
CLIENT,
SERVER
}
}
Loading
Loading