[PATCH 9/9] vinyl: throttle tx to ensure compaction keeps up with dumps

Vladimir Davydov vdavydov.dev at gmail.com
Mon Jan 21 17:14:04 MSK 2019


On Mon, Jan 21, 2019 at 12:17:08AM +0300, Vladimir Davydov wrote:
> +void
> +vy_regulator_update_rate_limit(struct vy_regulator *regulator,
> +			       const struct vy_scheduler_stat *stat,
> +			       int compaction_threads)
> +{
> +	struct vy_scheduler_stat *last = &regulator->sched_stat_last;
> +	struct vy_scheduler_stat *recent = &regulator->sched_stat_recent;
> +	/*
> +	 * The maximal dump rate the database can handle while
> +	 * maintaining the current level of write amplification
> +	 * equals:
> +	 *
> +	 *                                        dump_output
> +	 *   max_dump_rate = compaction_rate * -----------------
> +	 *                                     compaction_output
> +	 *
> +	 * The average compaction rate can be estimated with:
> +	 *
> +	 *                                          compaction_output
> +	 *   compaction_rate = compaction_threads * -----------------
> +	 *                                           compaction_time
> +	 *
> +	 * Putting it all together and taking into account data
> +	 * compaction during memory dump, we get for the max
> +	 * transaction rate:
> +	 *
> +	 *                                 dump_input
> +	 *   max_tx_rate = max_dump_rate * ----------- =
> +	 *                                 dump_output
> +	 *
> +	 *                                        dump_input
> +	 *                 compaction_threads * ---------------
> +	 *                                      compaction_time
> +	 *
> +	 * We set the rate limit to half that to leave the database
> +	 * engine enough room needed for growing write amplification.
> +	 */
> +	recent->dump_count += stat->dump_count - last->dump_count;
> +	recent->dump_input += stat->dump_input - last->dump_input;
> +	recent->compaction_time += stat->compaction_time -
> +				   last->compaction_time;
> +	*last = *stat;
> +
> +	if (recent->compaction_time == 0 ||
> +	    recent->dump_input < (int)VY_DUMP_SIZE_ACCT_MIN)
> +		return;
> +
> +	double rate = 0.5 * compaction_threads * recent->dump_input /
> +						 recent->compaction_time;
> +	vy_quota_set_rate_limit(regulator->quota, VY_QUOTA_RESOURCE_DISK,
> +				MIN(rate, SIZE_MAX));
> +
> +	/*
> +	 * Periodically rotate statistics for quicker adaptation
> +	 * to workload changes.
> +	 */
> +	if (recent->dump_count > VY_RECENT_DUMP_COUNT) {
> +		recent->dump_count /= 2;
> +		recent->dump_input /= 2;
> +		recent->compaction_time /= 2;
> +	}
> +}

vinyl/deferreted_delete.test.lua generates very small dumps (several
KBs). If the disk is slow, which is the case on Travis CI, the overhead
associated with file creation will be too high in comparison to the
amount of work done by compaction, and so the rate limit will be set to
a very small value, stalling the test. I fixed this on the branch by
completely ignoring any dump less than 1 MB, as we do when estimating
dump bandwidth. The incremental diff is below.

diff --git a/src/box/vy_regulator.c b/src/box/vy_regulator.c
index b406cf97..75f1f798 100644
--- a/src/box/vy_regulator.c
+++ b/src/box/vy_regulator.c
@@ -322,16 +322,18 @@ vy_regulator_update_rate_limit(struct vy_regulator *regulator,
 	 * We set the rate limit to half that to leave the database
 	 * engine enough room needed for growing write amplification.
 	 */
-	recent->dump_count += stat->dump_count - last->dump_count;
-	recent->dump_input += stat->dump_input - last->dump_input;
-	recent->compaction_time += stat->compaction_time -
-				   last->compaction_time;
+	int32_t dump_count = stat->dump_count - last->dump_count;
+	int64_t dump_input = stat->dump_input - last->dump_input;
+	double compaction_time = stat->compaction_time - last->compaction_time;
 	*last = *stat;
 
-	if (recent->compaction_time == 0 ||
-	    recent->dump_input < (int)VY_DUMP_SIZE_ACCT_MIN)
+	if (dump_input < (ssize_t)VY_DUMP_SIZE_ACCT_MIN)
 		return;
 
+	recent->dump_count += dump_count;
+	recent->dump_input += dump_input;
+	recent->compaction_time += compaction_time;
+
 	double rate = 0.5 * compaction_threads * recent->dump_input /
 						 recent->compaction_time;
 	vy_quota_set_rate_limit(regulator->quota, VY_QUOTA_RESOURCE_DISK,



More information about the Tarantool-patches mailing list