Skip to content

Commit 990ddc3

Browse files
authored
Read write ephemeral objects for remote publication of cluster state (opensearch-project#14089)
* Read and write ephemeral objects for remote publication Co-authored-by: Sooraj Sinha <soosinha@amazon.com> Co-authored-by: Arpit Bandejiya <abandeji@amazon.com> Signed-off-by: Shivansh Arora <hishiv@amazon.com> * Add serde logic for hashes of consistent settings Signed-off-by: Sooraj Sinha <soosinha@amazon.com> * Add formattedName to readAsync for IndexMetadata Signed-off-by: Shivansh Arora <hishiv@amazon.com>
1 parent 4c25257 commit 990ddc3

29 files changed

+1347
-223
lines changed

server/src/main/java/org/opensearch/cluster/RepositoryCleanupInProgress.java

+36
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import java.util.ArrayList;
4646
import java.util.Collections;
4747
import java.util.List;
48+
import java.util.Objects;
4849

4950
/**
5051
* Information passed during repository cleanup
@@ -118,6 +119,24 @@ public Version getMinimalSupportedVersion() {
118119
return LegacyESVersion.fromId(7040099);
119120
}
120121

122+
@Override
123+
public boolean equals(Object o) {
124+
if (this == o) {
125+
return true;
126+
}
127+
if (o == null || getClass() != o.getClass()) {
128+
return false;
129+
}
130+
131+
RepositoryCleanupInProgress that = (RepositoryCleanupInProgress) o;
132+
return entries.equals(that.entries);
133+
}
134+
135+
@Override
136+
public int hashCode() {
137+
return 31 + entries.hashCode();
138+
}
139+
121140
/**
122141
* Entry in the collection.
123142
*
@@ -155,6 +174,23 @@ public void writeTo(StreamOutput out) throws IOException {
155174
out.writeLong(repositoryStateId);
156175
}
157176

177+
@Override
178+
public boolean equals(Object o) {
179+
if (this == o) {
180+
return true;
181+
}
182+
if (o == null || getClass() != o.getClass()) {
183+
return false;
184+
}
185+
RepositoryCleanupInProgress.Entry that = (RepositoryCleanupInProgress.Entry) o;
186+
return repository.equals(that.repository) && repositoryStateId == that.repositoryStateId;
187+
}
188+
189+
@Override
190+
public int hashCode() {
191+
return Objects.hash(repository, repositoryStateId);
192+
}
193+
158194
@Override
159195
public String toString() {
160196
return "{" + repository + '}' + '{' + repositoryStateId + '}';

server/src/main/java/org/opensearch/cluster/metadata/Metadata.java

+4
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,10 @@ public static boolean isTemplatesMetadataEqual(Metadata metadata1, Metadata meta
981981
return metadata1.templates.equals(metadata2.templates);
982982
}
983983

984+
public static boolean isHashesOfConsistentSettingsEqual(Metadata metadata1, Metadata metadata2) {
985+
return metadata1.hashesOfConsistentSettings.equals(metadata2.hashesOfConsistentSettings);
986+
}
987+
984988
public static boolean isCustomMetadataEqual(Metadata metadata1, Metadata metadata2) {
985989
int customCount1 = 0;
986990
for (Map.Entry<String, Custom> cursor : metadata1.customs.entrySet()) {

server/src/main/java/org/opensearch/cluster/routing/RoutingTable.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public class RoutingTable implements Iterable<IndexRoutingTable>, Diffable<Routi
7979
// index to IndexRoutingTable map
8080
private final Map<String, IndexRoutingTable> indicesRouting;
8181

82-
private RoutingTable(long version, final Map<String, IndexRoutingTable> indicesRouting) {
82+
public RoutingTable(long version, final Map<String, IndexRoutingTable> indicesRouting) {
8383
this.version = version;
8484
this.indicesRouting = Collections.unmodifiableMap(indicesRouting);
8585
}

server/src/main/java/org/opensearch/cluster/routing/remote/InternalRemoteRoutingTableService.java

+70-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.opensearch.common.util.io.IOUtils;
3434
import org.opensearch.core.action.ActionListener;
3535
import org.opensearch.core.common.bytes.BytesReference;
36+
import org.opensearch.core.index.Index;
3637
import org.opensearch.gateway.remote.ClusterMetadataManifest;
3738
import org.opensearch.gateway.remote.RemoteStateTransferException;
3839
import org.opensearch.gateway.remote.routingtable.RemoteIndexRoutingTable;
@@ -44,11 +45,14 @@
4445
import org.opensearch.repositories.RepositoriesService;
4546
import org.opensearch.repositories.Repository;
4647
import org.opensearch.repositories.blobstore.BlobStoreRepository;
48+
import org.opensearch.threadpool.ThreadPool;
4749

4850
import java.io.IOException;
4951
import java.util.ArrayList;
5052
import java.util.List;
5153
import java.util.Map;
54+
import java.util.Optional;
55+
import java.util.concurrent.ExecutorService;
5256
import java.util.function.Function;
5357
import java.util.function.Supplier;
5458
import java.util.stream.Collectors;
@@ -97,11 +101,13 @@ public class InternalRemoteRoutingTableService extends AbstractLifecycleComponen
97101
private BlobStoreRepository blobStoreRepository;
98102
private RemoteStoreEnums.PathType pathType;
99103
private RemoteStoreEnums.PathHashAlgorithm pathHashAlgo;
104+
private ThreadPool threadPool;
100105

101106
public InternalRemoteRoutingTableService(
102107
Supplier<RepositoriesService> repositoriesService,
103108
Settings settings,
104-
ClusterSettings clusterSettings
109+
ClusterSettings clusterSettings,
110+
ThreadPool threadpool
105111
) {
106112
assert isRemoteRoutingTableEnabled(settings) : "Remote routing table is not enabled";
107113
this.repositoriesService = repositoriesService;
@@ -110,6 +116,7 @@ public InternalRemoteRoutingTableService(
110116
this.pathHashAlgo = clusterSettings.get(REMOTE_ROUTING_TABLE_PATH_HASH_ALGO_SETTING);
111117
clusterSettings.addSettingsUpdateConsumer(REMOTE_ROUTING_TABLE_PATH_TYPE_SETTING, this::setPathTypeSetting);
112118
clusterSettings.addSettingsUpdateConsumer(REMOTE_ROUTING_TABLE_PATH_HASH_ALGO_SETTING, this::setPathHashAlgoSetting);
119+
this.threadPool = threadpool;
113120
}
114121

115122
private void setPathTypeSetting(RemoteStoreEnums.PathType pathType) {
@@ -266,6 +273,68 @@ private void uploadIndex(
266273
}
267274
}
268275

276+
@Override
277+
public CheckedRunnable<IOException> getAsyncIndexRoutingReadAction(
278+
String uploadedFilename,
279+
Index index,
280+
LatchedActionListener<IndexRoutingTable> latchedActionListener
281+
) {
282+
int idx = uploadedFilename.lastIndexOf("/");
283+
String blobFileName = uploadedFilename.substring(idx + 1);
284+
BlobContainer blobContainer = blobStoreRepository.blobStore()
285+
.blobContainer(BlobPath.cleanPath().add(uploadedFilename.substring(0, idx)));
286+
287+
return () -> readAsync(
288+
blobContainer,
289+
blobFileName,
290+
index,
291+
threadPool.executor(ThreadPool.Names.REMOTE_STATE_READ),
292+
ActionListener.wrap(
293+
response -> latchedActionListener.onResponse(response.getIndexRoutingTable()),
294+
latchedActionListener::onFailure
295+
)
296+
);
297+
}
298+
299+
private void readAsync(
300+
BlobContainer blobContainer,
301+
String name,
302+
Index index,
303+
ExecutorService executorService,
304+
ActionListener<RemoteIndexRoutingTable> listener
305+
) {
306+
executorService.execute(() -> {
307+
try {
308+
listener.onResponse(read(blobContainer, name, index));
309+
} catch (Exception e) {
310+
listener.onFailure(e);
311+
}
312+
});
313+
}
314+
315+
private RemoteIndexRoutingTable read(BlobContainer blobContainer, String path, Index index) {
316+
try {
317+
return new RemoteIndexRoutingTable(blobContainer.readBlob(path), index);
318+
} catch (IOException | AssertionError e) {
319+
logger.error(() -> new ParameterizedMessage("RoutingTable read failed for path {}", path), e);
320+
throw new RemoteStateTransferException("Failed to read RemoteRoutingTable from Manifest with error ", e);
321+
}
322+
}
323+
324+
@Override
325+
public List<ClusterMetadataManifest.UploadedIndexMetadata> getUpdatedIndexRoutingTableMetadata(
326+
List<String> updatedIndicesRouting,
327+
List<ClusterMetadataManifest.UploadedIndexMetadata> allIndicesRouting
328+
) {
329+
return updatedIndicesRouting.stream().map(idx -> {
330+
Optional<ClusterMetadataManifest.UploadedIndexMetadata> uploadedIndexMetadataOptional = allIndicesRouting.stream()
331+
.filter(idx2 -> idx2.getIndexName().equals(idx))
332+
.findFirst();
333+
assert uploadedIndexMetadataOptional.isPresent() == true;
334+
return uploadedIndexMetadataOptional.get();
335+
}).collect(Collectors.toList());
336+
}
337+
269338
private String getIndexRoutingFileName(long term, long version) {
270339
return String.join(
271340
DELIMITER,

server/src/main/java/org/opensearch/cluster/routing/remote/NoopRemoteRoutingTableService.java

+21
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.opensearch.common.CheckedRunnable;
1717
import org.opensearch.common.blobstore.BlobPath;
1818
import org.opensearch.common.lifecycle.AbstractLifecycleComponent;
19+
import org.opensearch.core.index.Index;
1920
import org.opensearch.gateway.remote.ClusterMetadataManifest;
2021

2122
import java.io.IOException;
@@ -57,6 +58,26 @@ public List<ClusterMetadataManifest.UploadedIndexMetadata> getAllUploadedIndices
5758
List<ClusterMetadataManifest.UploadedIndexMetadata> indicesRoutingUploaded,
5859
List<String> indicesRoutingToDelete
5960
) {
61+
// noop
62+
return List.of();
63+
}
64+
65+
@Override
66+
public CheckedRunnable<IOException> getAsyncIndexRoutingReadAction(
67+
String uploadedFilename,
68+
Index index,
69+
LatchedActionListener<IndexRoutingTable> latchedActionListener
70+
) {
71+
// noop
72+
return () -> {};
73+
}
74+
75+
@Override
76+
public List<ClusterMetadataManifest.UploadedIndexMetadata> getUpdatedIndexRoutingTableMetadata(
77+
List<String> updatedIndicesRouting,
78+
List<ClusterMetadataManifest.UploadedIndexMetadata> allIndicesRouting
79+
) {
80+
// noop
6081
return List.of();
6182
}
6283

server/src/main/java/org/opensearch/cluster/routing/remote/RemoteRoutingTableService.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@
1818
import org.opensearch.common.lifecycle.LifecycleComponent;
1919
import org.opensearch.core.common.io.stream.StreamInput;
2020
import org.opensearch.core.common.io.stream.StreamOutput;
21+
import org.opensearch.core.index.Index;
2122
import org.opensearch.gateway.remote.ClusterMetadataManifest;
2223

2324
import java.io.IOException;
2425
import java.util.List;
2526
import java.util.Map;
2627

2728
/**
28-
* Interface for RemoteRoutingTableService. Exposes methods to orchestrate upload and download of routing table from remote store.
29+
* A Service which provides APIs to upload and download routing table from remote store.
30+
*
31+
* @opensearch.internal
2932
*/
3033
public interface RemoteRoutingTableService extends LifecycleComponent {
3134
public static final DiffableUtils.NonDiffableValueSerializer<String, IndexRoutingTable> CUSTOM_ROUTING_TABLE_VALUE_SERIALIZER =
@@ -43,6 +46,17 @@ public IndexRoutingTable read(StreamInput in, String key) throws IOException {
4346

4447
List<IndexRoutingTable> getIndicesRouting(RoutingTable routingTable);
4548

49+
CheckedRunnable<IOException> getAsyncIndexRoutingReadAction(
50+
String uploadedFilename,
51+
Index index,
52+
LatchedActionListener<IndexRoutingTable> latchedActionListener
53+
);
54+
55+
List<ClusterMetadataManifest.UploadedIndexMetadata> getUpdatedIndexRoutingTableMetadata(
56+
List<String> updatedIndicesRouting,
57+
List<ClusterMetadataManifest.UploadedIndexMetadata> allIndicesRouting
58+
);
59+
4660
DiffableUtils.MapDiff<String, IndexRoutingTable, Map<String, IndexRoutingTable>> getIndicesRoutingMapDiff(
4761
RoutingTable before,
4862
RoutingTable after

server/src/main/java/org/opensearch/cluster/routing/remote/RemoteRoutingTableServiceFactory.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.opensearch.common.settings.ClusterSettings;
1212
import org.opensearch.common.settings.Settings;
1313
import org.opensearch.repositories.RepositoriesService;
14+
import org.opensearch.threadpool.ThreadPool;
1415

1516
import java.util.function.Supplier;
1617

@@ -26,15 +27,17 @@ public class RemoteRoutingTableServiceFactory {
2627
* @param repositoriesService repositoriesService
2728
* @param settings settings
2829
* @param clusterSettings clusterSettings
30+
* @param threadPool threadPool
2931
* @return RemoteRoutingTableService
3032
*/
3133
public static RemoteRoutingTableService getService(
3234
Supplier<RepositoriesService> repositoriesService,
3335
Settings settings,
34-
ClusterSettings clusterSettings
36+
ClusterSettings clusterSettings,
37+
ThreadPool threadPool
3538
) {
3639
if (isRemoteRoutingTableEnabled(settings)) {
37-
return new InternalRemoteRoutingTableService(repositoriesService, settings, clusterSettings);
40+
return new InternalRemoteRoutingTableService(repositoriesService, settings, clusterSettings, threadPool);
3841
}
3942
return new NoopRemoteRoutingTableService();
4043
}

server/src/main/java/org/opensearch/common/settings/ClusterSettings.java

+1
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ public void apply(Settings value, Settings current, Settings previous) {
724724
INDEX_METADATA_UPLOAD_TIMEOUT_SETTING,
725725
GLOBAL_METADATA_UPLOAD_TIMEOUT_SETTING,
726726
METADATA_MANIFEST_UPLOAD_TIMEOUT_SETTING,
727+
RemoteClusterStateService.REMOTE_STATE_READ_TIMEOUT_SETTING,
727728
RemoteStoreNodeService.REMOTE_STORE_COMPATIBILITY_MODE_SETTING,
728729
RemoteStoreNodeService.MIGRATION_DIRECTION_SETTING,
729730
IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING,

0 commit comments

Comments
 (0)