db_bench support for non-uniform column family ops

Summary:
Previously we could only select the CF on which to operate uniformly at random. This is a limitation, e.g., when testing universal compaction as all CFs would need to run full compaction at roughly the same time, which isn't realistic.

This PR allows the user to specify the probability distribution for selecting CFs via the `--column_family_distribution` argument.
Closes https://github.com/facebook/rocksdb/pull/2677

Differential Revision: D5544436

Pulled By: ajkr

fbshipit-source-id: 478d56260995236ae90895ce5bd51f38882e185a
This commit is contained in:
Andrew Kryczka 2017-08-11 13:46:41 -07:00 committed by Facebook Github Bot
parent 5de98f2d50
commit 74f18c1301

View File

@ -206,6 +206,15 @@ DEFINE_int32(
"create new set of column families and insert to them. Only used "
"when num_column_families > 1.");
DEFINE_string(column_family_distribution, "",
"Comma-separated list of percentages, where the ith element "
"indicates the probability of an op using the ith column family. "
"The number of elements must be `num_hot_column_families` if "
"specified; otherwise, it must be `num_column_families`. The "
"sum of elements must be 100. E.g., if `num_column_families=4`, "
"and `num_hot_column_families=0`, a valid list could be "
"\"10,20,30,40\".");
DEFINE_int64(reads, -1, "Number of read operations to do. "
"If negative, do FLAGS_num reads.");
@ -1198,6 +1207,8 @@ struct DBWithColumnFamilies {
// After each CreateNewCf(), another num_hot number of new
// Column families will be created and used to be queried.
port::Mutex create_cf_mutex; // Only one thread can execute CreateNewCf()
std::vector<int> cfh_idx_to_prob; // ith index holds probability of operating
// on cfh[i].
DBWithColumnFamilies()
: db(nullptr)
@ -1217,7 +1228,9 @@ struct DBWithColumnFamilies {
opt_txn_db(other.opt_txn_db),
#endif // ROCKSDB_LITE
num_created(other.num_created.load()),
num_hot(other.num_hot) {}
num_hot(other.num_hot),
cfh_idx_to_prob(other.cfh_idx_to_prob) {
}
void DeleteDBs() {
std::for_each(cfh.begin(), cfh.end(),
@ -1239,8 +1252,20 @@ struct DBWithColumnFamilies {
ColumnFamilyHandle* GetCfh(int64_t rand_num) {
assert(num_hot > 0);
size_t rand_offset = 0;
if (!cfh_idx_to_prob.empty()) {
assert(cfh_idx_to_prob.size() == num_hot);
int sum = 0;
while (sum + cfh_idx_to_prob[rand_offset] < rand_num % 100) {
sum += cfh_idx_to_prob[rand_offset];
++rand_offset;
}
assert(rand_offset < cfh_idx_to_prob.size());
} else {
rand_offset = rand_num % num_hot;
}
return cfh[num_created.load(std::memory_order_acquire) - num_hot +
rand_num % num_hot];
rand_offset];
}
// stage: assume CF from 0 to stage * num_hot has be created. Need to create
@ -3275,6 +3300,28 @@ void VerifyDBFromDB(std::string& truth_db_name) {
column_families.push_back(ColumnFamilyDescriptor(
ColumnFamilyName(i), ColumnFamilyOptions(options)));
}
std::vector<int> cfh_idx_to_prob;
if (!FLAGS_column_family_distribution.empty()) {
std::stringstream cf_prob_stream(FLAGS_column_family_distribution);
std::string cf_prob;
int sum = 0;
while (std::getline(cf_prob_stream, cf_prob, ',')) {
cfh_idx_to_prob.push_back(std::stoi(cf_prob));
sum += cfh_idx_to_prob.back();
}
if (sum != 100) {
fprintf(stderr, "column_family_distribution items must sum to 100\n");
exit(1);
}
if (cfh_idx_to_prob.size() != num_hot) {
fprintf(stderr,
"got %" ROCKSDB_PRIszt
" column_family_distribution items; expected "
"%" ROCKSDB_PRIszt "\n",
cfh_idx_to_prob.size(), num_hot);
exit(1);
}
}
#ifndef ROCKSDB_LITE
if (FLAGS_readonly) {
s = DB::OpenForReadOnly(options, db_name, column_families,
@ -3302,6 +3349,7 @@ void VerifyDBFromDB(std::string& truth_db_name) {
db->cfh.resize(FLAGS_num_column_families);
db->num_created = num_hot;
db->num_hot = num_hot;
db->cfh_idx_to_prob = std::move(cfh_idx_to_prob);
#ifndef ROCKSDB_LITE
} else if (FLAGS_readonly) {
s = DB::OpenForReadOnly(options, db_name, &db->db);