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

[Remote Compaction] Load latest options from OPTIONS file in Remote host #13025

Closed
wants to merge 5 commits into from

Conversation

jaykorean
Copy link
Contributor

@jaykorean jaykorean commented Sep 20, 2024

Summary

We've been serializing and deserializing DBOptions and CFOptions (and other CF into) as part of CompactionServiceInput. These are all readily available in the OPTIONS file and the remote worker can read the OPTIONS file to obtain the same information. This helps reducing the size of payload significantly.

In a very rare scenario if the OPTIONS file is purged due to options change by primary host at the same time while the remote host is loading the latest options, it may fail. In this case, we just retry once.

This also solves the problem where we had to open the default CF with the CFOption from another CF if the remote compaction is for a non-default column family. (TODO comment in /db_impl_secondary.cc)

Test Plan

Unit Tests

./compaction_service_test
./compaction_job_test

Also tested with Meta's internal Offload Infra

@jaykorean jaykorean marked this pull request as ready for review September 20, 2024 13:53
@facebook-github-bot
Copy link
Contributor

@jaykorean has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@jaykorean has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@jaykorean has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@@ -28,6 +29,13 @@ CompactionJob::ProcessKeyValueCompactionWithCompactionService(

const Compaction* compaction = sub_compact->compaction;
CompactionServiceInput compaction_input;
Status s = GetLatestOptionsFileName(dbname_, db_options_.env,
&compaction_input.options_file);
if (!s.ok()) {
Copy link
Member

Choose a reason for hiding this comment

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

Can the file be deleted before remote instance reads it?

Copy link
Contributor Author

@jaykorean jaykorean Sep 20, 2024

Choose a reason for hiding this comment

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

Ah good question. Yes, if options change between this line and remote worker trying to read the file, the file can be missing and we will have failure.

(Looks like we are purging the obsolete options file immediately after renaming the temp file.)

rocksdb/db/db_impl/db_impl.cc

Lines 5443 to 5450 in 71e38db

std::string file_name =
TempOptionsFileName(GetName(), versions_->NewFileNumber());
Status s = PersistRocksDBOptions(write_options, db_options, cf_names, cf_opts,
file_name, fs_.get());
if (s.ok()) {
s = RenameTempFileToOptionsFile(file_name);
}

Once the file is read from the remote worker, we don't need the file to exist anymore while the job is running. I'm wondering how often we could run into this issue in production and if this is something that we can tolerate. To even lower the chance, I think we can keep the last N OPTIONS file, which can be controlled behind an option. (for the users who change options often)

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you simply retry? The OPTIONS file should only change when SetDBOptions is called, which should be pretty rare.

Copy link
Contributor Author

@jaykorean jaykorean Sep 20, 2024

Choose a reason for hiding this comment

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

Could you simply retry?

Which one? I am not sure if retry on either of them would actually be helpful.

  1. For GetLatestOptionsFileName() in the primary host, I believe that it only fails if no OPTIONS file is found at all.
  2. For LoadOptionsFromFile(file_name_from_the_payload) in the remote worker, retry won't succeed if the file is gone.

Maybe I'm wondering if we should just call LoadLatestOptions() from the remote worker and always uses the latest options instead of passing the options file name over the payload.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just updated the PR to always load the latest options file instead of passing the file name in the payload. With a single retry, compaction failure due to missing OPTION file should be extremely rare.

@facebook-github-bot
Copy link
Contributor

@jaykorean has updated the pull request. You must reimport the pull request before landing.

@jaykorean jaykorean changed the title [Remote Compaction] Parse options from OPTIONS file instead of using CompactionServiceInput [Remote Compaction] Load latest options from OPTIONS file in Remote host Sep 20, 2024
@facebook-github-bot
Copy link
Contributor

@jaykorean has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Copy link
Member

@cbi42 cbi42 left a comment

Choose a reason for hiding this comment

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

LGTM

// In a very rare scenario, loading options may fail if the options changed by
// the primary host at the same time. Just retry once for now.
if (!s.ok()) {
s = LoadLatestOptions(config_options, name, &db_options,
Copy link
Member

Choose a reason for hiding this comment

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

Maybe log the error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually Logger is not available at this point before the options is loaded, so I didn't bother creating a tmp logger just for this. We can consider adding it later if really needed.

@facebook-github-bot
Copy link
Contributor

@jaykorean has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@jaykorean has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Copy link
Contributor

@anand1976 anand1976 left a comment

Choose a reason for hiding this comment

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

LGTM

@facebook-github-bot
Copy link
Contributor

@jaykorean merged this pull request in 5f4a8c3.

@jaykorean jaykorean deleted the remote_compaction_options branch September 20, 2024 21:25
facebook-github-bot pushed a commit that referenced this pull request Oct 16, 2024
Summary:
In #13025 , we made a change to load the latest options file in the remote worker instead of serializing the entire set of options.

That was done under assumption that OPTIONS file do not get purged often. While testing, we learned that this happens more often than we want it to be, so we want to prevent the OPTIONS file from getting purged anytime between when the remote compaction is scheduled and the option is loaded in the remote worker.

Like how we are protecting new SST files from getting purged using `min_pending_output`, we are doing the same by keeping track of `min_options_file_number`. Any OPTIONS file with number greater than `min_options_file_number` will be protected from getting purged. Just like `min_pending_output`, `min_options_file_number` gets bumped when the compaction is done. This is only applicable when `options.compaction_service` is set.

Pull Request resolved: #13074

Test Plan:
```
./compaction_service_test --gtest_filter="*PreservedOptionsLocalCompaction*"
./compaction_service_test --gtest_filter="*PreservedOptionsRemoteCompaction*"
```

Reviewed By: anand1976

Differential Revision: D64433795

Pulled By: jaykorean

fbshipit-source-id: 0d902773f0909d9481dec40abf0b4c54ce5e86b2
jaykorean added a commit that referenced this pull request Oct 17, 2024
Summary:
In #13025 , we made a change to load the latest options file in the remote worker instead of serializing the entire set of options.

That was done under assumption that OPTIONS file do not get purged often. While testing, we learned that this happens more often than we want it to be, so we want to prevent the OPTIONS file from getting purged anytime between when the remote compaction is scheduled and the option is loaded in the remote worker.

Like how we are protecting new SST files from getting purged using `min_pending_output`, we are doing the same by keeping track of `min_options_file_number`. Any OPTIONS file with number greater than `min_options_file_number` will be protected from getting purged. Just like `min_pending_output`, `min_options_file_number` gets bumped when the compaction is done. This is only applicable when `options.compaction_service` is set.

Pull Request resolved: #13074

Test Plan:
```
./compaction_service_test --gtest_filter="*PreservedOptionsLocalCompaction*"
./compaction_service_test --gtest_filter="*PreservedOptionsRemoteCompaction*"
```

Reviewed By: anand1976

Differential Revision: D64433795

Pulled By: jaykorean

fbshipit-source-id: 0d902773f0909d9481dec40abf0b4c54ce5e86b2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants