-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Remote Store] Add remote store restore API implementation #3642
[Remote Store] Add remote store restore API implementation #3642
Conversation
@@ -0,0 +1,211 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is added so that corresponding code in RestoreService
is compiled without any errors. This file is same as defined here: #3576
@@ -0,0 +1,103 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RestoreRemoteStoreRequest
file is added so that corresponding code in RestoreService is compiled without any errors. This file is same as defined here: #3576
✅ Gradle Check success f51871fa10b061f84cf18518d97ec7fb8b2eb134 |
57b52b6
to
405689c
Compare
✅ Gradle Check success 405689c53207cd7777a41b93d45923ba4c63df84 |
void recoverFromRemoteStore(final IndexShard indexShard, ActionListener<Boolean> listener) { | ||
if (canRecover(indexShard)) { | ||
RecoverySource.Type recoveryType = indexShard.recoveryState().getRecoverySource().getType(); | ||
assert recoveryType == RecoverySource.Type.REMOTE_STORE : "expected remote store recovery type but was: " + recoveryType; | ||
ActionListener.completeWith(recoveryListener(indexShard, listener), () -> { | ||
logger.debug("starting recovery from remote store ..."); | ||
recoverFromRemoteStore(indexShard); | ||
return true; | ||
}); | ||
} else { | ||
listener.onResponse(false); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we extend StoreRecovery
to RemoteStoreRecovery
and override recoverFromStore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StoreRecovery
currently contains: recoverFromStore
, recoverFromRepository
and recoverFromLocalShards
where the source of recovery is different for each of these methods. That is why I added one more method where recovery source is remote store.
* @param request restore request | ||
* @param listener restore listener | ||
*/ | ||
public void restoreFromRemoteStore(RestoreRemoteStoreRequest request, final ActionListener<RestoreCompletionResponse> listener) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method exists in the snapshot package, we should extend it and abstract it out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes,restoreSnapshot
method is in the same class. I earlier thought of extending it but RestoreSnapshotRequest
is different than RestoreRemoteStoreRequest
and even if we create one method, it will anyway have conditional check to redirect the flow to snapshot restore vs remote store restore.
public ClusterState execute(ClusterState currentState) { | ||
// Updating cluster state | ||
ClusterState.Builder builder = ClusterState.builder(currentState); | ||
Metadata.Builder mdBuilder = Metadata.builder(currentState.metadata()); | ||
ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks()); | ||
RoutingTable.Builder rtBuilder = RoutingTable.builder(currentState.routingTable()); | ||
|
||
List<String> indicesToBeRestored = new ArrayList<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we ensure concurrent snapshot recovery isn't happening? We need to sync on the shard state
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed adding a check in IndexRountingTable.initializeAsRemoteStoreRestore()
method. Will add.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing it out. Made change to handle this. #3642 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait! Forgot to commit index re-opening logic. Adding now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added code to open the closed index as part of restore flow.
405689c
to
a9efcc8
Compare
Signed-off-by: Sachin Kale <kalsac@amazon.com>
Signed-off-by: Sachin Kale <kalsac@amazon.com>
a9efcc8
to
374471d
Compare
Gradle Check (Jenkins) Run Completed with:
|
server/src/main/java/org/opensearch/index/shard/RemoteStoreRefreshListener.java
Outdated
Show resolved
Hide resolved
Gradle Check (Jenkins) Run Completed with:
|
374471d
to
527a653
Compare
Gradle Check (Jenkins) Run Completed with:
|
Test failing: |
Signed-off-by: Sachin Kale <kalsac@amazon.com>
527a653
to
e5809d0
Compare
Gradle Check (Jenkins) Run Completed with:
|
logger.warn("Remote store restore is not supported for non-existent index. Skipping: {}", index); | ||
continue; | ||
} | ||
if (currentIndexMetadata.getState() != IndexMetadata.State.CLOSE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We allow restore only for closed indices (similar to what snapshot does). Once index is set for recovery, index state is changed to open. This check enables us to avoid running two restores (remote/remote or remote/snapshot) at the same time.
Gradle Check (Jenkins) Run Completed with:
|
b0fb31e
to
e1bfcba
Compare
Gradle Check (Jenkins) Run Completed with:
|
Signed-off-by: Sachin Kale <kalsac@amazon.com>
e1bfcba
to
5f7baf9
Compare
Gradle Check (Jenkins) Run Completed with:
|
private IndicesOptions indicesOptions = IndicesOptions.strictExpandOpen(); | ||
private boolean waitForCompletion; | ||
|
||
public RestoreRemoteStoreRequest() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't indices be in constructor args(mandatory)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is handled by overriding ActionRequet
's validate() method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant just from a stand alone class perspective
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. It is a bit tricky as it depends on how RestRestoreRemoteStoreAction
initializes the RestoreRemoteStoreRequest
.
As indices is a part of post body, fetching it from RestRequest requires parsing the body content. This code of parsing is added as part of source
method of the same class.
I just followed the conventions used by other Request classes but open to suggestions.
super.writeTo(out); | ||
out.writeStringArray(indices); | ||
indicesOptions.writeIndicesOptions(out); | ||
out.writeBoolean(waitForCompletion); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
writeOptionalBoolean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed
if (name.equals("indices")) { | ||
if (entry.getValue() instanceof String) { | ||
indices(Strings.splitStringByCommaToArray((String) entry.getValue())); | ||
} else if (entry.getValue() instanceof ArrayList) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it be ArrayList?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As indices is part of post body, it is better to get it as map from the XContentParser
. This will help in easily adding new fields to the post body.
Signed-off-by: Sachin Kale <kalsac@amazon.com>
fad667a
to
e0d88ee
Compare
Gradle Check (Jenkins) Run Completed with:
|
Gradle Check (Jenkins) Run Completed with:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sachinpkale
Is it possible to restore just one shard rather than the complete index from remote store?
@Bukhtawar With the current flow, it makes an entry to the |
Created a tracking issue: #3768 |
…h-project#3642) * Add remote restore API implementation Signed-off-by: Sachin Kale <kalsac@amazon.com>
…h-project#3642) * Add remote restore API implementation Signed-off-by: Sachin Kale <kalsac@amazon.com>
…h-project#3642) * Add remote restore API implementation Signed-off-by: Sachin Kale <kalsac@amazon.com>
…4380) * [Remote Store] Upload segments to remote store post refresh (#3460) * Add RemoteDirectory interface to copy segment files to/from remote store Signed-off-by: Sachin Kale <kalsac@amazon.com> Co-authored-by: Sachin Kale <kalsac@amazon.com> * Add index level setting for remote store Signed-off-by: Sachin Kale <kalsac@amazon.com> Co-authored-by: Sachin Kale <kalsac@amazon.com> * Add RemoteDirectoryFactory and use RemoteDirectory instance in RefreshListener Co-authored-by: Sachin Kale <kalsac@amazon.com> Signed-off-by: Sachin Kale <kalsac@amazon.com> * Upload segment to remote store post refresh Signed-off-by: Sachin Kale <kalsac@amazon.com> Co-authored-by: Sachin Kale <kalsac@amazon.com> Signed-off-by: Sachin Kale <kalsac@amazon.com> * [Remote Store] Inject remote store in IndexShard instead of RemoteStoreRefreshListener (#3703) * Inject remote store in IndexShard instead of RemoteStoreRefreshListener Signed-off-by: Sachin Kale <kalsac@amazon.com> * Pass supplier of RepositoriesService to RemoteDirectoryFactory Signed-off-by: Sachin Kale <kalsac@amazon.com> * Create isRemoteStoreEnabled function for IndexShard Signed-off-by: Sachin Kale <kalsac@amazon.com> * Explicitly close remoteStore on indexShard close Signed-off-by: Sachin Kale <kalsac@amazon.com> * Change RemoteDirectory.close to a no-op Signed-off-by: Sachin Kale <kalsac@amazon.com> Co-authored-by: Sachin Kale <kalsac@amazon.com> * [Remote Store] Add remote store restore API implementation (#3642) * Add remote restore API implementation Signed-off-by: Sachin Kale <kalsac@amazon.com> * [Remote Store] Add support to add nested settings for remote store (#4060) * Add support to add nested settings for remote store Signed-off-by: Sachin Kale <kalsac@amazon.com> * [Remote Store] Add rest endpoint for remote store restore (#3576) * Add rest endpoint for remote store restore Signed-off-by: Sachin Kale <kalsac@amazon.com> * [Remote Store] Add validator that forces segment replication type before enabling remote store (#4175) * Add validator that forces segment replication type before enabling remote store Signed-off-by: Sachin Kale <kalsac@amazon.com> * [Remote Store] Change remote_store setting validation message to make it more clear (#4199) * Change remote_store setting validation message to make it more clear Signed-off-by: Sachin Kale <kalsac@amazon.com> * [Remote Store] Add RemoteSegmentStoreDirectory to interact with remote segment store (#4020) * Add RemoteSegmentStoreDirectory to interact with remote segment store Signed-off-by: Sachin Kale <kalsac@amazon.com> * Use RemoteSegmentStoreDirectory instead of RemoteDirectory (#4240) * Use RemoteSegmentStoreDirectory instead of RemoteDirectory Signed-off-by: Sachin Kale <kalsac@amazon.com> Signed-off-by: Sachin Kale <kalsac@amazon.com> Co-authored-by: Sachin Kale <kalsac@amazon.com>
Signed-off-by: Sachin Kale kalsac@amazon.com
Description
Issues Resolved
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.