Skip to content

Commit

Permalink
feat(config): add rocksdb.nocompression_for_first_levels to allow c…
Browse files Browse the repository at this point in the history
…onfigure levels without compression
  • Loading branch information
paragor committed Oct 17, 2024
1 parent 1d77232 commit 5fb1224
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 13 deletions.
9 changes: 9 additions & 0 deletions kvrocks.conf
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,15 @@ rocksdb.compression_level 32767
# Default: 2 MB
rocksdb.compaction_readahead_size 2097152

# Disable compression for first n levels.
# By default disabled for the first two levels, because it may contain the
# frequently accessed data, so it'd be better to use uncompressed data to
# save the CPU.
# Value: [0, 7] (upper boundary is rocksdb levels count)
#
# Default: 2
rocksdb.nocompression_for_first_n_levels 2

# he limited write rate to DB if soft_pending_compaction_bytes_limit or
# level0_slowdown_writes_trigger is triggered.

Expand Down
33 changes: 22 additions & 11 deletions src/config/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ Config::Config() {
new EnumField<rocksdb::CompressionType>(&rocks_db.compression, compression_types,
rocksdb::CompressionType::kNoCompression)},
{"rocksdb.compression_level", true, new IntField(&rocks_db.compression_level, 32767, INT_MIN, INT_MAX)},
// can't be more than rocksdb levels count
{"rocksdb.nocompression_for_first_n_levels", false,
new IntField(&rocks_db.nocompression_for_first_n_levels, 2, 0, 7)},
{"rocksdb.block_size", true, new IntField(&rocks_db.block_size, 16384, 0, INT_MAX)},
{"rocksdb.max_open_files", false, new IntField(&rocks_db.max_open_files, 8096, -1, INT_MAX)},
{"rocksdb.write_buffer_size", false, new IntField(&rocks_db.write_buffer_size, 64, 0, 4096)},
Expand Down Expand Up @@ -368,12 +371,11 @@ void Config::initFieldCallback() {
return srv->storage->SetOptionForAllColumnFamilies(TrimRocksDbPrefix(k), v);
};
auto set_compression_type_cb = [](Server *srv, [[maybe_unused]] const std::string &k,
const std::string &v) -> Status {
[[maybe_unused]] const std::string &v) -> Status {
if (!srv) return Status::OK();

std::string compression_option;
for (auto &option : engine::CompressionOptions) {
if (option.name == v) {
if (option.type == srv->GetConfig()->rocks_db.compression) {
compression_option = option.val;
break;
}
Expand All @@ -382,15 +384,23 @@ void Config::initFieldCallback() {
return {Status::NotOK, "Invalid compression type"};
}

// For the first two levels, it may contain the frequently accessed data,
// so it'd be better to use uncompressed data to save the CPU.
std::string compression_levels = "kNoCompression:kNoCompression";
auto db = srv->storage->GetDB();
for (size_t i = 2; i < db->GetOptions().compression_per_level.size(); i++) {
compression_levels += ":";
compression_levels += compression_option;
const int nocompression_for_first_n_levels = srv->GetConfig()->rocks_db.nocompression_for_first_n_levels;
const int compression_per_level_size = srv->storage->GetDB()->GetOptions().compression_per_level.size();
if (nocompression_for_first_n_levels > compression_per_level_size) {
return {Status::NotOK, "nocompression_for_first_n_levels must <= rocksdb levels count"};
}
std::vector<std::string> compression_per_level_builder;
compression_per_level_builder.reserve(compression_per_level_size);

for (int i = 0; i < nocompression_for_first_n_levels; i++) {
compression_per_level_builder.emplace_back("kNoCompression");
}
for (int i = nocompression_for_first_n_levels; i < compression_per_level_size; i++) {
compression_per_level_builder.emplace_back(compression_option);
}
return srv->storage->SetOptionForAllColumnFamilies("compression_per_level", compression_levels);
const std::string compression_per_level = util::StringJoin(
compression_per_level_builder, [](const auto &s) -> decltype(auto) { return s; }, ":");
return srv->storage->SetOptionForAllColumnFamilies("compression_per_level", compression_per_level);
};
#ifdef ENABLE_OPENSSL
auto set_tls_option = [](Server *srv, [[maybe_unused]] const std::string &k, [[maybe_unused]] const std::string &v) {
Expand Down Expand Up @@ -696,6 +706,7 @@ void Config::initFieldCallback() {
{"rocksdb.level0_stop_writes_trigger", set_cf_option_cb},
{"rocksdb.level0_file_num_compaction_trigger", set_cf_option_cb},
{"rocksdb.compression", set_compression_type_cb},
{"rocksdb.nocompression_for_first_n_levels", set_compression_type_cb},
#ifdef ENABLE_OPENSSL
{"tls-cert-file", set_tls_option},
{"tls-key-file", set_tls_option},
Expand Down
1 change: 1 addition & 0 deletions src/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ struct Config {
int level0_stop_writes_trigger;
int level0_file_num_compaction_trigger;
rocksdb::CompressionType compression;
int nocompression_for_first_n_levels;
int compression_level;
bool disable_auto_compactions;
bool enable_blob_files;
Expand Down
3 changes: 1 addition & 2 deletions src/storage/storage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,8 @@ rocksdb::Options Storage::InitRocksDBOptions() {
options.num_levels = 7;
options.compression_opts.level = config_->rocks_db.compression_level;
options.compression_per_level.resize(options.num_levels);
// only compress levels >= 2
for (int i = 0; i < options.num_levels; ++i) {
if (i < 2) {
if (i < config_->rocks_db.nocompression_for_first_n_levels) {
options.compression_per_level[i] = rocksdb::CompressionType::kNoCompression;
} else {
options.compression_per_level[i] = config_->rocks_db.compression;
Expand Down
1 change: 1 addition & 0 deletions tests/cppunit/config_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ TEST(Config, GetAndSet) {
{"rocksdb.max_bytes_for_level_multiplier", "10"},
{"rocksdb.level_compaction_dynamic_level_bytes", "yes"},
{"rocksdb.max_background_jobs", "4"},
{"rocksdb.nocompression_for_first_n_levels", "2"},
};
std::vector<std::string> values;
for (const auto &iter : mutable_cases) {
Expand Down

0 comments on commit 5fb1224

Please sign in to comment.