Skip to content

Commit aacf60d

Browse files
ajkrfacebook-github-bot
authored andcommitted
Speedup based on number of files marked for compaction (#12306)
Summary: RocksDB self throttles per-DB compaction parallelism until it detects compaction pressure. This PR adds pressure detection based on the number of files marked for compaction. Pull Request resolved: #12306 Reviewed By: cbi42 Differential Revision: D53200559 Pulled By: ajkr fbshipit-source-id: 63402ee336881a4539204d255960f04338ab7a0e
1 parent 61ed0de commit aacf60d

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

db/column_family.cc

+18
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,14 @@ uint64_t GetPendingCompactionBytesForCompactionSpeedup(
893893
uint64_t size_threshold = bottommost_files_size / kBottommostSizeDivisor;
894894
return std::min(size_threshold, slowdown_threshold);
895895
}
896+
897+
uint64_t GetMarkedFileCountForCompactionSpeedup() {
898+
// When just one file is marked, it is not clear that parallel compaction will
899+
// help the compaction that the user nicely requested to happen sooner. When
900+
// multiple files are marked, however, it is pretty clearly helpful, except
901+
// for the rare case in which a single compaction grabs all the marked files.
902+
return 2;
903+
}
896904
} // anonymous namespace
897905

898906
std::pair<WriteStallCondition, WriteStallCause>
@@ -1074,6 +1082,16 @@ WriteStallCondition ColumnFamilyData::RecalculateWriteStallConditions(
10741082
"compaction "
10751083
"bytes %" PRIu64,
10761084
name_.c_str(), vstorage->estimated_compaction_needed_bytes());
1085+
} else if (uint64_t(vstorage->FilesMarkedForCompaction().size()) >=
1086+
GetMarkedFileCountForCompactionSpeedup()) {
1087+
write_controller_token_ =
1088+
write_controller->GetCompactionPressureToken();
1089+
ROCKS_LOG_INFO(
1090+
ioptions_.logger,
1091+
"[%s] Increasing compaction threads because we have %" PRIu64
1092+
" files marked for compaction",
1093+
name_.c_str(),
1094+
uint64_t(vstorage->FilesMarkedForCompaction().size()));
10771095
} else {
10781096
write_controller_token_.reset();
10791097
}

db/column_family_test.cc

+69
Original file line numberDiff line numberDiff line change
@@ -3020,6 +3020,75 @@ TEST_P(ColumnFamilyTest, CompactionSpeedupForCompactionDebt) {
30203020
}
30213021
}
30223022

3023+
TEST_P(ColumnFamilyTest, CompactionSpeedupForMarkedFiles) {
3024+
const int kParallelismLimit = 3;
3025+
class AlwaysCompactTpc : public TablePropertiesCollector {
3026+
public:
3027+
Status Finish(UserCollectedProperties* /* properties */) override {
3028+
return Status::OK();
3029+
}
3030+
3031+
UserCollectedProperties GetReadableProperties() const override {
3032+
return UserCollectedProperties{};
3033+
}
3034+
3035+
const char* Name() const override { return "AlwaysCompactTpc"; }
3036+
3037+
bool NeedCompact() const override { return true; }
3038+
};
3039+
3040+
class AlwaysCompactTpcf : public TablePropertiesCollectorFactory {
3041+
public:
3042+
TablePropertiesCollector* CreateTablePropertiesCollector(
3043+
TablePropertiesCollectorFactory::Context /* context */) override {
3044+
return new AlwaysCompactTpc();
3045+
}
3046+
3047+
const char* Name() const override { return "AlwaysCompactTpcf"; }
3048+
};
3049+
3050+
column_family_options_.num_levels = 2;
3051+
column_family_options_.table_properties_collector_factories.emplace_back(
3052+
std::make_shared<AlwaysCompactTpcf>());
3053+
db_options_.max_background_compactions = kParallelismLimit;
3054+
Open();
3055+
3056+
// Make a nonempty last level. Only marked files in upper levels count.
3057+
ASSERT_OK(db_->Put(WriteOptions(), "foo", "bar"));
3058+
ASSERT_OK(db_->Flush(FlushOptions()));
3059+
WaitForCompaction();
3060+
AssertFilesPerLevel("0,1", 0 /* cf */);
3061+
3062+
// Block the compaction thread pool so marked files accumulate in L0.
3063+
test::SleepingBackgroundTask sleeping_tasks[kParallelismLimit];
3064+
for (int i = 0; i < kParallelismLimit; i++) {
3065+
env_->Schedule(&test::SleepingBackgroundTask::DoSleepTask,
3066+
&sleeping_tasks[i], Env::Priority::LOW);
3067+
sleeping_tasks[i].WaitUntilSleeping();
3068+
}
3069+
3070+
// Zero marked upper-level files. No speedup.
3071+
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
3072+
AssertFilesPerLevel("0,1", 0 /* cf */);
3073+
3074+
// One marked upper-level file. No speedup.
3075+
ASSERT_OK(db_->Put(WriteOptions(), "foo", "bar"));
3076+
ASSERT_OK(db_->Flush(FlushOptions()));
3077+
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
3078+
AssertFilesPerLevel("1,1", 0 /* cf */);
3079+
3080+
// Two marked upper-level files. Speedup.
3081+
ASSERT_OK(db_->Put(WriteOptions(), "foo", "bar"));
3082+
ASSERT_OK(db_->Flush(FlushOptions()));
3083+
ASSERT_EQ(kParallelismLimit, dbfull()->TEST_BGCompactionsAllowed());
3084+
AssertFilesPerLevel("2,1", 0 /* cf */);
3085+
3086+
for (int i = 0; i < kParallelismLimit; i++) {
3087+
sleeping_tasks[i].WakeUp();
3088+
sleeping_tasks[i].WaitUntilDone();
3089+
}
3090+
}
3091+
30233092
TEST_P(ColumnFamilyTest, CreateAndDestroyOptions) {
30243093
std::unique_ptr<ColumnFamilyOptions> cfo(new ColumnFamilyOptions());
30253094
ColumnFamilyHandle* cfh;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Compactions can be scheduled in parallel in an additional scenario: multiple files are marked for compaction within a single column family

0 commit comments

Comments
 (0)