Skip to content
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

Deduplicate Index Metadata in BlobStore #50278

Conversation

original-brownbear
Copy link
Member

@original-brownbear original-brownbear commented Dec 17, 2019

This PR introduces two new fields in to RepositoryData (index-N) to track the blob name of IndexMetaData blobs and their content hashes. This is used to deduplicate the IndexMetaData blobs (meta-{uuid}.dat in the indices folders under /indices so that new metadata for an index is only written to the repository during a snapshot if that same metadata can't be found in another snapshot.
This saves one write per index in the common case of unchanged metadata thus saving cost and making snapshot finalization drastically faster if many indices are being snapshotted at the same time.

The implementation is mostly analogous to that for shard generations in #46250 and piggy backs on the BwC mechanism introduced in that PR (which means this PR needs adjustments if it doesn't go into 7.6).

Relates to #45736 as it improves the efficiency of snapshotting unchanged indices
Relates to #49800 as it has the potential of loading the index metadata for multiple snapshots of the same index concurrently much more efficient speeding up future concurrent snapshot delete

@original-brownbear original-brownbear added >enhancement WIP :Distributed/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs labels Dec 17, 2019
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-distributed (:Distributed/Snapshot/Restore)

}
// TODO: assertEquals(indexMetaGenerationsExpected, indexMetaGenerationsFound); requires cleanup functionality for
// index meta generations blobs
assertTrue(indexMetaGenerationsFound.containsAll(indexMetaGenerationsExpected));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not checking equality here makes this test somewhat redundant admittedly but I figured it was ncie to leave the logic and TODO here to make it clear why we need index metadata blob cleanup.
Note, the fact that we leak index metadata blobs is not new and can happen without this change as well. As a matter of fact, you could argue that it is more likely to leak index metadata blobs before this change since there's simply more of them and the delete timing hasn't changed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test that checks that index metadata is cleaned up if it is no longer referenced? (i.e. a succeeding snapshot delete that was holding the last reference to that index metadata)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enhanced the test for metadata deduplication in c9ab2fc to cover this explicitly

* @param snapshotId the snapshot id to load the index metadata from
* @param index the {@link IndexId} to load the metadata from
* @return the index metadata about the given index for the given snapshot
*/
IndexMetaData getSnapshotIndexMetaData(SnapshotId snapshotId, IndexId index) throws IOException;
IndexMetaData getSnapshotIndexMetaData(RepositoryData repositoryData, SnapshotId snapshotId, IndexId index) throws IOException;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of an awkward API to pass the RepositoryData here again admittedly, but as you can see from the diff we have the RepositoryData available 100% of the time in production code when calling this method so I didn't see a reason to make this call more expensive, slower and less stable by forcing another round trip to loading repositoryData just so that I can keep the simpler API.


final Executor executor = threadPool.executor(ThreadPool.Names.SNAPSHOT);

getRepositoryData(ActionListener.wrap(existingRepositoryData -> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to reviewers: There's no big change here. Just moved out the loading of repository data to be the first step so that we have it available for the index metadata writer threads for the lookup and removed its lazy loading from allMetaListener below, all other changes are just indent changes.

@original-brownbear original-brownbear marked this pull request as ready for review December 18, 2019 08:53
original-brownbear added a commit to original-brownbear/elasticsearch that referenced this pull request May 25, 2020
Pre-requesite for elastic#50278 to be able to uniquely identify index metadata by
its version fields and UUIDs when restoring into closed indices.
original-brownbear added a commit that referenced this pull request May 25, 2020
Pre-requesite for #50278 to be able to uniquely identify index metadata by
its version fields and UUIDs when restoring into closed indices.
@original-brownbear
Copy link
Member Author

original-brownbear commented May 29, 2020

@ywelsch @tlrx I made use of #56930 to better track the uniqueness of index metadata => this PR should be good for review again at last :) (not urgent though)

Copy link
Contributor

@ywelsch ywelsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left some small comments, looking good o.w.

}
// TODO: assertEquals(indexMetaGenerationsExpected, indexMetaGenerationsFound); requires cleanup functionality for
// index meta generations blobs
assertTrue(indexMetaGenerationsFound.containsAll(indexMetaGenerationsExpected));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test that checks that index metadata is cleaned up if it is no longer referenced? (i.e. a succeeding snapshot delete that was holding the last reference to that index metadata)

@original-brownbear
Copy link
Member Author

Thanks Yannick, sorry for the merge error, fixed now + test added:)

@original-brownbear
Copy link
Member Author

Jenkins run elasticsearch-ci/2 (unrelated xpack)

Copy link
Contributor

@ywelsch ywelsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@original-brownbear
Copy link
Member Author

Thanks Yannick!

@original-brownbear original-brownbear merged commit 37ab351 into elastic:master Jun 5, 2020
@original-brownbear original-brownbear deleted the deduplicate-index-metadata branch June 5, 2020 17:16
original-brownbear added a commit to original-brownbear/elasticsearch that referenced this pull request Jul 14, 2020
This PR introduces two new fields in to `RepositoryData` (index-N) to track the blob name of `IndexMetaData` blobs and their content via setting generations and uuids. This is used to deduplicate the `IndexMetaData` blobs (`meta-{uuid}.dat` in the indices folders under `/indices` so that new metadata for an index is only written to the repository during a snapshot if that same metadata can't be found in another snapshot.
This saves one write per index in the common case of unchanged metadata thus saving cost and making snapshot finalization drastically faster if many indices are being snapshotted at the same time.

The implementation is mostly analogous to that for shard generations in elastic#46250 and piggy backs on the BwC mechanism introduced in that PR (which means this PR needs adjustments if it doesn't go into `7.6`).

Relates to elastic#45736 as it improves the efficiency of snapshotting unchanged indices
Relates to elastic#49800 as it has the potential of loading the index metadata for multiple snapshots of the same index concurrently much more efficient speeding up future concurrent snapshot delete
original-brownbear added a commit that referenced this pull request Jul 14, 2020
This PR introduces two new fields in to `RepositoryData` (index-N) to track the blob name of `IndexMetaData` blobs and their content via setting generations and uuids. This is used to deduplicate the `IndexMetaData` blobs (`meta-{uuid}.dat` in the indices folders under `/indices` so that new metadata for an index is only written to the repository during a snapshot if that same metadata can't be found in another snapshot.
This saves one write per index in the common case of unchanged metadata thus saving cost and making snapshot finalization drastically faster if many indices are being snapshotted at the same time.

The implementation is mostly analogous to that for shard generations in #46250 and piggy backs on the BwC mechanism introduced in that PR (which means this PR needs adjustments if it doesn't go into `7.6`).

Relates to #45736 as it improves the efficiency of snapshotting unchanged indices
Relates to #49800 as it has the potential of loading the index metadata for multiple snapshots of the same index concurrently much more efficient speeding up future concurrent snapshot delete
@original-brownbear original-brownbear restored the deduplicate-index-metadata branch August 6, 2020 18:25
@original-brownbear original-brownbear deleted the deduplicate-index-metadata branch December 1, 2020 12:51
@original-brownbear original-brownbear restored the deduplicate-index-metadata branch December 6, 2020 18:59
@original-brownbear original-brownbear deleted the deduplicate-index-metadata branch January 20, 2021 09:04
@original-brownbear original-brownbear restored the deduplicate-index-metadata branch April 18, 2023 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs >enhancement Team:Distributed Meta label for distributed team v7.9.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants