Skip to content

Commit

Permalink
db bench: usability of the pinning policy parameter (#720)
Browse files Browse the repository at this point in the history
  • Loading branch information
udi-speedb authored Oct 19, 2023
1 parent dc39061 commit 8c68304
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 15 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* LOG Reporting: add reporting capabilities to the WriteController and the WriteBufferManager by saving the Loggers of the dbs which are using them internally and issuing WARN msgs to these Loggers whenever the state of the WC and WBM changes in regards to delaying (#556).
* Enable speedb features: Use Scoped Pinning Policy in Enable speedb feature (#459).
* sst_dump: display metaindex_handle and the index_handle's offset and size in footer information (#404).
* db_bench: Add support for individual scoped pinning policy parameters (#687).

### Bug Fixes
* db_bench: Fix SeekRandomWriteRandom valid check. Use key and value only after checking iterator is valid.
Expand Down
8 changes: 7 additions & 1 deletion db_stress_tool/db_stress_gflags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#ifdef GFLAGS
#include "db_stress_tool/db_stress_common.h"
#include "table/block_based/default_pinning_policy.h"

static bool ValidateUint32Range(const char* flagname, uint64_t value) {
if (value > std::numeric_limits<uint32_t>::max()) {
Expand Down Expand Up @@ -890,7 +891,12 @@ DEFINE_string(fs_uri, "",
" with --env_uri."
" Creates a default environment with the specified filesystem.");

DEFINE_string(pinning_policy, "", "URI for registry TablePinningPolicy");
DEFINE_string(pinning_policy,
ROCKSDB_NAMESPACE::DefaultPinningPolicy::kNickName(),
"The pinning policy to use. "
"The options are: "
"'DefaultPinning': Default RocksDB's pinning polcy. "
"'ScopedPinning': Speedb's Scoped pinning policy.");

DEFINE_uint64(ops_per_thread, 1200000, "Number of operations per thread.");
static const bool FLAGS_ops_per_thread_dummy __attribute__((__unused__)) =
Expand Down
9 changes: 8 additions & 1 deletion db_stress_tool/db_stress_test_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "db_stress_tool/db_stress_compaction_filter.h"
#include "db_stress_tool/db_stress_driver.h"
#include "db_stress_tool/db_stress_table_properties_collector.h"
#include "plugin/speedb/pinning_policy/scoped_pinning_policy.h"
#include "rocksdb/convenience.h"
#include "rocksdb/filter_policy.h"
#include "rocksdb/options.h"
Expand All @@ -43,6 +44,7 @@
#include "rocksdb/utilities/object_registry.h"
#include "rocksdb/utilities/write_batch_with_index.h"
#include "speedb/version.h"
#include "table/block_based/default_pinning_policy.h"
#include "test_util/testutil.h"
#include "util/cast_util.h"
#include "utilities/backup/backup_engine_impl.h"
Expand Down Expand Up @@ -3167,11 +3169,16 @@ void InitializeOptionsFromFlags(
block_based_options.num_file_reads_for_auto_readahead =
FLAGS_num_file_reads_for_auto_readahead;
if (!FLAGS_pinning_policy.empty()) {
auto pinning_policy_uri = DefaultPinningPolicy::kClassName();
if (FLAGS_pinning_policy == DefaultPinningPolicy::kNickName()) {
pinning_policy_uri = ScopedPinningPolicy::kClassName();
}

ConfigOptions config_options;
config_options.ignore_unknown_options = false;
config_options.ignore_unsupported_options = false;
Status s = TablePinningPolicy::CreateFromString(
config_options, FLAGS_pinning_policy,
config_options, pinning_policy_uri,
&block_based_options.pinning_policy);
if (!s.ok()) {
fprintf(stderr, "Failed to create PinningPolicy: %s\n",
Expand Down
12 changes: 8 additions & 4 deletions plugin/speedb/pinning_policy/scoped_pinning_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,28 @@ namespace ROCKSDB_NAMESPACE {
struct TablePinningOptions;
struct ScopedPinningOptions {
static const char* kName() { return "ScopedPinningOptions"; }

static constexpr uint32_t kDefaultLastLevelWithDataPercent = 10;
static constexpr uint32_t kDefaultMidPercent = 80;

// Limit to how much data should be pinned
size_t capacity = 1024 * 1024 * 1024; // 1GB

// Percent of capacity at which not to pin last-leve-with-data data
uint32_t last_level_with_data_percent = 10;
uint32_t last_level_with_data_percent = kDefaultLastLevelWithDataPercent;

// Percent of capacity at which not to pin non-L0 data
uint32_t mid_percent = 80;
uint32_t mid_percent = kDefaultMidPercent;
};

// A table policy that limits the size of the data to be pinned
//
class ScopedPinningPolicy : public RecordingPinningPolicy {
public:
ScopedPinningPolicy();
ScopedPinningPolicy(const ScopedPinningOptions& options);

static const char* kClassName() { return "speedb_scoped_pinning_policy"; }
static const char* kNickName() { return "speedb.ScopedPinningPolicy"; }
static const char* kNickName() { return "scoped"; }
const char* Name() const override { return kClassName(); }
const char* NickName() const override { return kNickName(); }
std::string GetId() const override;
Expand Down
2 changes: 2 additions & 0 deletions table/block_based/default_pinning_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ class DefaultPinningPolicy : public RecordingPinningPolicy {
bool pin_l0);

static const char* kClassName() { return "DefaultPinningPolicy"; }
static const char* kNickName() { return "default"; }
const char* Name() const override { return kClassName(); }
const char* NickName() const override { return kNickName(); }

protected:
bool CheckPin(const TablePinningOptions& tpo, uint8_t type, size_t /*size*/,
Expand Down
2 changes: 2 additions & 0 deletions table/block_based/table_pinning_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ class DefaultPinningPolicy : public RecordingPinningPolicy {
//**TODO: Register options?
}
static const char* kClassName() { return "DefaultPinningPolicy"; }
static const char* kNickName() { return "DefaultPinning"; }
const char* Name() const override { return kClassName(); }
const char* NickName() const override { return kNickName(); }

protected:
bool CheckPin(const TablePinningOptions& tpo, uint8_t type, size_t /*size*/,
Expand Down
107 changes: 99 additions & 8 deletions tools/db_bench_tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include "monitoring/histogram.h"
#include "monitoring/statistics.h"
#include "options/cf_options.h"
#include "plugin/speedb/pinning_policy/scoped_pinning_policy.h"
#include "port/port.h"
#include "port/stack_trace.h"
#include "rocksdb/cache.h"
Expand Down Expand Up @@ -92,6 +93,7 @@
#include "rocksdb/write_batch.h"
#include "rocksdb/write_buffer_manager.h"
#include "speedb/version.h"
#include "table/block_based/default_pinning_policy.h"
#include "test_util/testutil.h"
#include "test_util/transaction_test_util.h"
#include "tools/simulated_hybrid_file_system.h"
Expand Down Expand Up @@ -818,7 +820,32 @@ DEFINE_bool(
" Note `cache_index_and_filter_blocks` must be true for this option to have"
" any effect.");

DEFINE_string(pinning_policy, "", "URI for registry TablePinningPolicy");
DEFINE_string(pinning_policy,
ROCKSDB_NAMESPACE::DefaultPinningPolicy::kNickName(),
"The pinning policy to use. "
"The options are: "
"'default': Default RocksDB's pinning polcy. "
"'scoped': Speedb's Scoped pinning policy.");

DEFINE_int32(scoped_pinning_capacity, -1,
"Pinning policy capacity. The default (-1) results in the "
"capacity being calculated "
"automatically. If the capacity is >= 0, the specified value will "
"be the capacity. Applicable only when pinning_policy=='Scoped'.");

DEFINE_int32(
scoped_pinning_last_level_with_data_percent,
ROCKSDB_NAMESPACE::ScopedPinningOptions::kDefaultLastLevelWithDataPercent,
"Max percent of the pinning capacity to pin entites that are at "
"the bottom-most possible level."
"Applicable only when pinning_policy=='Scoped'.");

DEFINE_int32(scoped_pinning_mid_percent,
ROCKSDB_NAMESPACE::ScopedPinningOptions::kDefaultMidPercent,
"Max percent of the pinning capacity to pin entites that are "
"above the bottom-most level,but at a >0 level. "
"Must be >= scoped_pinning_last_level_with_data_percent. "
"Applicable only when pinning_policy=='Scoped'.");

DEFINE_int32(block_size,
static_cast<int32_t>(
Expand Down Expand Up @@ -4817,14 +4844,28 @@ class Benchmark {
} else {
fprintf(stdout, "Integrated BlobDB: blob cache disabled\n");
}
if (!FLAGS_pinning_policy.empty()) {
s = TablePinningPolicy::CreateFromString(
config_options, FLAGS_pinning_policy,
&block_based_options.pinning_policy);
if (!s.ok()) {
ErrorExit("Could not create pinning policy: %s",
s.ToString().c_str());

if (FLAGS_pinning_policy ==
ROCKSDB_NAMESPACE::ScopedPinningPolicy::kNickName()) {
ScopedPinningOptions pinning_options;

size_t pinning_capacity = 0U;
if (FLAGS_scoped_pinning_capacity >= 0) {
pinning_capacity = FLAGS_scoped_pinning_capacity;
} else {
auto cache_capacity = FLAGS_cache_size;
if (FLAGS_cost_write_buffer_to_cache) {
assert(cache_capacity >= FLAGS_db_write_buffer_size);
cache_capacity -= FLAGS_db_write_buffer_size;
}
pinning_capacity = (80 * cache_capacity) / 100;
}
pinning_options.capacity = pinning_capacity;
pinning_options.last_level_with_data_percent =
FLAGS_scoped_pinning_last_level_with_data_percent;
pinning_options.mid_percent = FLAGS_scoped_pinning_mid_percent;
block_based_options.pinning_policy =
std::make_shared<ScopedPinningPolicy>(pinning_options);
}

options.table_factory.reset(
Expand Down Expand Up @@ -9279,6 +9320,55 @@ void ValidateMetadataCacheOptions() {
}
}

void ValidatePinningRelatedOptions() {
if (FLAGS_pinning_policy ==
ROCKSDB_NAMESPACE::DefaultPinningPolicy::kNickName()) {
return;
} else if (FLAGS_pinning_policy ==
ROCKSDB_NAMESPACE::ScopedPinningPolicy::kNickName()) {
if (FLAGS_cache_index_and_filter_blocks == false) {
ErrorExit(
"--cache_index_and_filter_blocks must be set when "
"--pinning_policy=='%s' to have any affect.",
ROCKSDB_NAMESPACE::ScopedPinningPolicy::kNickName());
}

if (FLAGS_scoped_pinning_capacity < -1) {
ErrorExit(
"--scoped_pinning_capacity must be either -1 (auto-calc) or >= 0");
}

if ((FLAGS_scoped_pinning_last_level_with_data_percent < 0) ||
(FLAGS_scoped_pinning_last_level_with_data_percent > 100)) {
ErrorExit(
"--scoped_pinning_last_level_with_data_percent must be between 0 and "
"100");
}

if ((FLAGS_scoped_pinning_mid_percent < 0) ||
(FLAGS_scoped_pinning_mid_percent > 100)) {
ErrorExit("--scoped_pinning_mid_percent must be between 0 and 100");
}

if (FLAGS_scoped_pinning_last_level_with_data_percent >=
FLAGS_scoped_pinning_mid_percent) {
ErrorExit(
"--scoped_pinning_last_level_with_data_percent must be <= "
"--scoped_pinning_mid_percent must be between 0 and 100");
}

if (FLAGS_cost_write_buffer_to_cache) {
if (FLAGS_db_write_buffer_size > FLAGS_cache_size) {
ErrorExit("--cache_size must be >= --db_write_buffer_size");
}
}
} else {
ErrorExit("--pinning_policy must be either %s or %s",
ROCKSDB_NAMESPACE::DefaultPinningPolicy::kNickName(),
ROCKSDB_NAMESPACE::ScopedPinningPolicy::kNickName());
}
}

namespace {
// Records the values of applicable flags during the invocation of the first
// group The user may not modify any of these in subsequent groups
Expand Down Expand Up @@ -9605,6 +9695,7 @@ int db_bench_tool_run_group(int group_num, int num_groups, int argc,
}

ValidateMetadataCacheOptions();
ValidatePinningRelatedOptions();
ParseSanitizeAndValidateMultipleDBsFlags(first_group);

if (first_group) {
Expand Down
6 changes: 5 additions & 1 deletion tools/db_crashtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@
"customopspercent": 0,
# "filter_uri": lambda: random.choice(["speedb.PairedBloomFilter", ""]),
"memtablerep": lambda: random.choice(["skip_list", "hash_spdb"]),
"pinning_policy": lambda: random.choice(["", "speedb_scoped_pinning_policy"]),
"pinning_policy": lambda: random.choice(["DefaultPinning", "ScopedPinning"]),
"use_dynamic_delay": lambda: random.choice([0, 1, 1, 1]),
"allow_wbm_stalls": lambda: random.randint(0, 1),
"start_delay_percent": lambda: random.randint(0, 99),
Expand Down Expand Up @@ -767,6 +767,10 @@ def finalize_and_sanitize(src_params, counter):
dest_params["bloom_bits"] = random.choice([random.randint(1,19),
random.lognormvariate(2.3, 1.3)])

# db_bench will abort if using ScopedPinningPolicy and not setting cache_index_and_filter_blocks
if dest_params.get("pinning_policy") == "ScopedPinning":
dest_params["cache_index_and_filter_blocks"]

return dest_params


Expand Down

0 comments on commit 8c68304

Please sign in to comment.