Skip to content

Commit b09e27b

Browse files
Ryan Hancockfacebook-github-bot
authored andcommitted
Add MultiScan DB Bench Benchmark (facebook#13765)
Summary: This diff add's a DB Bench Benchmark dedicated to sequential non-overlapping sets of scans using the MultiScan API. Pull Request resolved: facebook#13765 Test Plan: ``` make release // Setup the DB ./db_bench --db=$DB \ --benchmarks="fillseq,compact" \ --disable_wal=1 --key_size=$KEYSIZE \ --value_size=$VALUESIZE --num=$NUMKEYS --threads=32 // Run the benchmark ./db_bench --use_existing_db=1 \ --benchmarks=multiscan \ --disable_auto_compactions=1 --seek_nexts=1000 \ --key_size=$KEYSIZE --value_size=$VALUESIZE \ --num=$NUMKEYS --threads=32 --duration=30 ``` Reviewed By: anand1976 Differential Revision: D78129962 Pulled By: krhancoc fbshipit-source-id: 1c524d531b62a8576374ed1377e29d59a83cedec
1 parent 0788cb8 commit b09e27b

1 file changed

Lines changed: 82 additions & 2 deletions

File tree

tools/db_bench_tool.cc

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ DEFINE_string(
129129
"compact1,"
130130
"waitforcompaction,"
131131
"multireadrandom,"
132+
"multiscan,"
132133
"mixgraph,"
133134
"readseq,"
134135
"readtorowcache,"
@@ -333,6 +334,13 @@ DEFINE_bool(use_uint64_comparator, false, "use Uint64 user comparator");
333334

334335
DEFINE_int64(batch_size, 1, "Batch size");
335336

337+
DEFINE_int64(multiscan_size, 10,
338+
"MultiScan size - number of multiscans of size `batch_size`");
339+
340+
DEFINE_int64(
341+
multiscan_stride, 100,
342+
"The amount of keys between two successive Scan operations in multiscan");
343+
336344
static bool ValidateKeySize(const char* /*flagname*/, int32_t /*value*/) {
337345
return true;
338346
}
@@ -2190,7 +2198,8 @@ enum OperationType : unsigned char {
21902198
kUncompress,
21912199
kCrc,
21922200
kHash,
2193-
kOthers
2201+
kOthers,
2202+
kMultiScan
21942203
};
21952204

21962205
static std::unordered_map<OperationType, std::string, std::hash<unsigned char>>
@@ -2199,7 +2208,7 @@ static std::unordered_map<OperationType, std::string, std::hash<unsigned char>>
21992208
{kMerge, "merge"}, {kUpdate, "update"},
22002209
{kCompress, "compress"}, {kCompress, "uncompress"},
22012210
{kCrc, "crc"}, {kHash, "hash"},
2202-
{kOthers, "op"}};
2211+
{kOthers, "op"}, {kMultiScan, "multiscan"}};
22032212

22042213
class CombinedStats;
22052214
class Stats {
@@ -3641,6 +3650,12 @@ class Benchmark {
36413650
fprintf(stderr, "entries_per_batch = %" PRIi64 "\n",
36423651
entries_per_batch_);
36433652
method = &Benchmark::MultiReadRandom;
3653+
} else if (name == "multiscan") {
3654+
fprintf(stderr, "multiscan_stride = %" PRIi64 "\n",
3655+
FLAGS_multiscan_stride);
3656+
fprintf(stderr, "multiscan_size = %" PRIi64 "\n", FLAGS_multiscan_size);
3657+
fprintf(stderr, "seek_nexts = %" PRIi32 "\n", FLAGS_seek_nexts);
3658+
method = &Benchmark::MultiScan;
36443659
} else if (name == "multireadwhilewriting") {
36453660
fprintf(stderr, "entries_per_batch = %" PRIi64 "\n",
36463661
entries_per_batch_);
@@ -6369,6 +6384,71 @@ class Benchmark {
63696384
thread->stats.AddMessage(msg);
63706385
}
63716386

6387+
void MultiScan(ThreadState* thread) {
6388+
const int64_t scan_size = FLAGS_seek_nexts ? FLAGS_seek_nexts : 50;
6389+
const int64_t readahead =
6390+
FLAGS_readahead_size ? FLAGS_readahead_size : 1024 * 24;
6391+
const int64_t multiscan_size = FLAGS_multiscan_size;
6392+
auto count_hist = std::make_shared<HistogramImpl>();
6393+
ReadOptions options = read_options_;
6394+
6395+
int64_t multiscans_done = 0;
6396+
6397+
options.async_io = true;
6398+
options.readahead_size = readahead;
6399+
6400+
Duration duration(FLAGS_duration, reads_);
6401+
while (!duration.Done(1)) {
6402+
DB* db = SelectDB(thread);
6403+
std::vector<ScanOptions> opts;
6404+
std::vector<std::unique_ptr<const char[]>> guards;
6405+
opts.reserve(multiscan_size);
6406+
// We create 1 random start, and then multiscan will start from that
6407+
// random start point And create a set of scans of `scan_size` in size
6408+
// with `multiscan_stride` space between each scan.
6409+
uint64_t range = static_cast<uint64_t>(FLAGS_num) -
6410+
((scan_size + FLAGS_multiscan_stride) * multiscan_size);
6411+
uint64_t start_key = thread->rand.Uniform(range);
6412+
for (int64_t i = 0; i < multiscan_size; i++) {
6413+
std::unique_ptr<const char[]> skey_guard;
6414+
Slice skey = AllocateKey(&skey_guard);
6415+
guards.push_back(std::move(skey_guard));
6416+
std::unique_ptr<const char[]> ekey_guard;
6417+
Slice ekey = AllocateKey(&ekey_guard);
6418+
guards.push_back(std::move(ekey_guard));
6419+
6420+
GenerateKeyFromInt(start_key, FLAGS_num, &skey);
6421+
uint64_t end_key = start_key + scan_size;
6422+
GenerateKeyFromInt(end_key, FLAGS_num, &ekey);
6423+
6424+
opts.emplace_back(skey, ekey);
6425+
start_key += scan_size + FLAGS_multiscan_stride;
6426+
}
6427+
6428+
auto iter =
6429+
db->NewMultiScan(read_options_, db->DefaultColumnFamily(), opts);
6430+
for (auto rng : *iter) {
6431+
size_t keys = 0;
6432+
for (auto it __attribute__((__unused__)) : rng) {
6433+
keys++;
6434+
}
6435+
assert(keys > 0);
6436+
}
6437+
6438+
if (thread->shared->read_rate_limiter.get() != nullptr) {
6439+
thread->shared->read_rate_limiter->Request(
6440+
1, Env::IO_HIGH, nullptr /* stats */, RateLimiter::OpType::kRead);
6441+
}
6442+
6443+
thread->stats.FinishedOps(nullptr, db, 1, kMultiScan);
6444+
multiscans_done += 1;
6445+
}
6446+
6447+
char msg[100];
6448+
snprintf(msg, sizeof(msg), "(multscans:%" PRIu64 ")", multiscans_done);
6449+
thread->stats.AddMessage(msg);
6450+
}
6451+
63726452
void ApproximateMemtableStats(ThreadState* thread) {
63736453
const size_t batch_size = entries_per_batch_;
63746454
std::unique_ptr<const char[]> skey_guard;

0 commit comments

Comments
 (0)