From b1ff9ac9c5cf30d0fcd23291fb51a257bfa5acee Mon Sep 17 00:00:00 2001 From: Mark Callaghan Date: Wed, 17 Apr 2013 10:56:39 -0700 Subject: [PATCH] Add --writes_per_second rate limit, print p99.99 in histogram Summary: Adds the --writes_per_second rate limit for the readwhilewriting test. The purpose is to optionally avoid saturating storage with writes & compaction and test read response time when some writes are being done. Changes the histogram code to also print the p99.99 value Task ID: # Blame Rev: Test Plan: make check, ran db_bench with it Revert Plan: Database Impact: Memcache Impact: Other Notes: EImportant: - begin *PUBLIC* platform impact section - Bugzilla: # - end platform impact - Reviewers: haobo Reviewed By: haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D10305 --- db/db_bench.cc | 31 ++++++++++++++++++++++++++++++- util/histogram.cc | 6 ++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/db/db_bench.cc b/db/db_bench.cc index acab62636..b73fce310 100644 --- a/db/db_bench.cc +++ b/db/db_bench.cc @@ -162,6 +162,10 @@ static class std::shared_ptr dbstats; // Number of write operations to do. If negative, do FLAGS_num reads. static long FLAGS_writes = -1; +// Per-thread rate limit on writes per second. No limit when <= 0. +// Only for the readwhilewriting test. +static int FLAGS_writes_per_second = 0; + // These default values might change if the hardcoded // Sync all writes to disk @@ -579,6 +583,7 @@ class Benchmark { fprintf(stdout, "FileSize: %.1f MB (estimated)\n", (((FLAGS_key_size + FLAGS_value_size * FLAGS_compression_ratio) * num_) / 1048576.0)); + fprintf(stdout, "Write rate limit: %d\n", FLAGS_writes_per_second); switch (FLAGS_compression_type) { case leveldb::kNoCompression: @@ -1296,7 +1301,6 @@ unique_ptr GenerateKeyFromInt(int v) } void DoDelete(ThreadState* thread, bool seq) { - RandomGenerator gen; WriteBatch batch; Status s; Duration duration(seq ? 0 : FLAGS_duration, num_); @@ -1332,6 +1336,15 @@ unique_ptr GenerateKeyFromInt(int v) } else { // Special thread that keeps writing until other threads are done. RandomGenerator gen; + double last = FLAGS_env->NowMicros(); + int writes_per_second_by_10 = 0; + int num_writes = 0; + + // --writes_per_second rate limit is enforced per 100 milliseconds + // intervals to avoid a burst of writes at the start of each second. + + if (FLAGS_writes_per_second > 0) + writes_per_second_by_10 = FLAGS_writes_per_second / 10; // Don't merge stats from this thread with the readers. thread->stats.SetExcludeFromMerge(); @@ -1353,6 +1366,20 @@ unique_ptr GenerateKeyFromInt(int v) exit(1); } thread->stats.FinishedSingleOp(db_); + + ++num_writes; + if (writes_per_second_by_10 && num_writes >= writes_per_second_by_10) { + double now = FLAGS_env->NowMicros(); + double usecs_since_last = now - last; + + num_writes = 0; + last = now; + + if (usecs_since_last < 100000.0) { + FLAGS_env->SleepForMicroseconds(100000.0 - usecs_since_last); + last = FLAGS_env->NowMicros(); + } + } } } } @@ -1779,6 +1806,8 @@ int main(int argc, char** argv) { } } else if (sscanf(argv[i], "--writes=%d%c", &n, &junk) == 1) { FLAGS_writes = n; + } else if (sscanf(argv[i], "--writes_per_second=%d%c", &n, &junk) == 1) { + FLAGS_writes_per_second = n; } else if (sscanf(argv[i], "--sync=%d%c", &n, &junk) == 1 && (n == 0 || n == 1)) { FLAGS_sync = n; diff --git a/util/histogram.cc b/util/histogram.cc index 9728d68b7..f232138a0 100644 --- a/util/histogram.cc +++ b/util/histogram.cc @@ -152,8 +152,10 @@ std::string HistogramImpl::ToString() const { (num_ == 0.0 ? 0.0 : min_), Median(), max_); r.append(buf); snprintf(buf, sizeof(buf), - "Percentiles: P50: %.2f P75: %.2f P99: %.2f P99.9: %.2f\n", - Percentile(50), Percentile(75), Percentile(99), Percentile(99.9)); + "Percentiles: " + "P50: %.2f P75: %.2f P99: %.2f P99.9: %.2f P99.99: %.2f\n", + Percentile(50), Percentile(75), Percentile(99), Percentile(99.9), + Percentile(99.99)); r.append(buf); r.append("------------------------------------------------------\n"); const double mult = 100.0 / num_;