Skip to content

Commit

Permalink
Auto: first linear delay then exp delay
Browse files Browse the repository at this point in the history
2/3 is linear and the rest (rounded down) is exp.
  • Loading branch information
Yuval-Ariel committed Feb 20, 2024
1 parent cd21d63 commit 59b2fa5
Showing 1 changed file with 39 additions and 22 deletions.
61 changes: 39 additions & 22 deletions db/column_family.cc
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ int GetL0ThresholdSpeedupCompaction(int level0_file_num_compaction_trigger,
namespace {
const int kMemtablePenalty = 5;
const int kNumPendingSteps = 100;
const double kGoalMbs = 5242880.0;
const double kGoalMbs = 3 * 1048576.0;
} // namespace

double ColumnFamilyData::TEST_CalculateWriteDelayDivider(
Expand Down Expand Up @@ -1040,8 +1040,7 @@ ColumnFamilyData::CalculateWriteDelayDividerAndMaybeUpdateWriteStallCause(
// This is calculated and set when the L0L1 compaction ends in
// CompactionJob::Install.
// Use this rate for the first extra slowdown files and then heavily delay the
// rest of the files. In any case, delay at least 2
// * trigger.
// rest of the files. In any case, delay at least 2 * trigger.

// slowdown 12 ; stop 30; - start at 22
// slowdown 12 ; stop 50; - start at 24
Expand All @@ -1054,33 +1053,51 @@ ColumnFamilyData::CalculateWriteDelayDividerAndMaybeUpdateWriteStallCause(
auto gap = stop - slowdown;
if ((gap > (slowdown + 2 * trigger))) {
file_to_start_delay = slowdown + 2 * trigger;
} else if (slowdown + (2 * trigger) < stop) {
file_to_start_delay = slowdown + trigger;
} else {
file_to_start_delay = slowdown;
}
// The goal is to reach kGoalMbs 3 steps before stop condition so that we
// never reach it. The formula to decide the delay percentage is: kGoalMbs =
// start_rate * (delay_percent ^ num_steps) where: kGoalMbs = 5 , start_rate
// is the l0_compaction_speed num_steps = num_L0_steps - 3.
// Initial delay (2/3 of the steps) is done linearly to avoid a big delay
// early on and the rest is exponential. For the exponential part, the goal is
// to reach kGoalMbs 1 step before stop condition so that we never reach it.
// The formula to decide the delay percentage is: kGoalMbs = start_rate *
// (delay_percent ^ num_delay_steps) where: start_rate is the rate at the last
// linear step, and num_delay_steps is num_steps_till_stop - 1.
double l0_divider = 1;
const int kGoalMbStep = 1;
const auto extra_l0_ssts =
vstorage->l0_delay_trigger_count() - file_to_start_delay;
if (extra_l0_ssts > 0) {
const auto num_L0_steps = stop - file_to_start_delay;
assert(num_L0_steps > 0);
double num_steps = num_L0_steps > 6 ? num_L0_steps - 1 : num_L0_steps;
auto base = (kGoalMbs / 5) / l0_base_compaction_speed();
// in cases where l0_base_compaction_speed() is lower than our goal Mbs
if (base > 1) {
base = 0.95;
const auto num_steps_till_stop = stop - file_to_start_delay;
assert(num_steps_till_stop > 0);
double num_delay_steps = num_steps_till_stop - kGoalMbStep;
const int linear_steps = num_delay_steps * (2.0 / 3);
const auto initial_linear_rate = l0_base_compaction_speed();
const int mb_per_linear_step =
(initial_linear_rate - kGoalMbs) / num_delay_steps;
if (extra_l0_ssts <= linear_steps) {
double l0_files_rate =
initial_linear_rate - (extra_l0_ssts * mb_per_linear_step);
assert(l0_files_rate > 0);
l0_divider = initial_linear_rate / l0_files_rate;
} else {
// calculate exponential delay from last linear step.
auto last_linear_step_mbs =
initial_linear_rate - (linear_steps * mb_per_linear_step);
auto base = kGoalMbs / last_linear_step_mbs;
// in cases where last_linear_step_mbs is lower than our goal Mbs
if (base > 1) {
base = 0.95;
}
auto num_exp_steps = num_delay_steps - linear_steps;
double delay_percent = std::pow(base, 1.0 / num_exp_steps);
assert(delay_percent > 0 && delay_percent < 1);
// since extra_l0_ssts == num_steps_till_stop then we're in a stop
// condition.
assert(extra_l0_ssts < num_steps_till_stop);
auto l0_rate = last_linear_step_mbs *
std::pow(delay_percent, (extra_l0_ssts - linear_steps));
l0_divider = initial_linear_rate / l0_rate;
}
double delay_percent = std::pow(base, 1.0 / num_steps);
assert(delay_percent > 0 && delay_percent < 1);
// since extra_l0_ssts == num_L0_steps then we're in a stop condition.
assert(extra_l0_ssts < num_L0_steps);

l0_divider = 1 / (std::pow(delay_percent, extra_l0_ssts));
}

if (l0_divider > biggest_divider) {
Expand Down

0 comments on commit 59b2fa5

Please sign in to comment.