Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions kvrocks.conf
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,29 @@ rocksdb.cache_index_and_filter_blocks yes
# default snappy
rocksdb.compression snappy

# Specify the compression level to use. It trades compression speed
# and ratio, might be useful when tuning for disk space.
# See details: https://github.com/facebook/rocksdb/wiki/Space-Tuning
# For zstd: valid range is from 1 (fastest) to 19 (best ratio),
# For zlib: valid range is from 1 (fastest) to 9 (best ratio),
# For lz4: adjusting the level influences the 'acceleration'.
# RocksDB sets a negative level to indicate acceleration directly,
# with more negative values indicating higher speed and less compression.
# Note: This setting is ignored for compression algorithms like Snappy that
# do not support variable compression levels.
#
# RocksDB Default:
# - zstd: 3
# - zlib: Z_DEFAULT_COMPRESSION (currently -1)
# - kLZ4: -1 (i.e., `acceleration=1`; see `CompressionOptions::level` doc)
# For all others, RocksDB does not specify a compression level.
# If the compression type doesn't support the setting, it will be a no-op.
#
# Default: 32767 (RocksDB's generic default compression level. Internally
# it'll be translated to the default compression level specific to the
# compression library as mentioned above)
rocksdb.compression_level 32767

# If non-zero, we perform bigger reads when doing compaction. If you're
# running RocksDB on spinning disks, you should set this to at least 2MB.
# That way RocksDB's compaction is doing sequential instead of random reads.
Expand Down
1 change: 1 addition & 0 deletions src/config/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ Config::Config() {
{"rocksdb.compression", false,
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)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔why compression_level can be dynamically changed?

Copy link
Member Author

@Beihao-Zhou Beihao-Zhou Mar 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, my bad. I mean why it's different from compression, which could be changed dynamically.

This looks ok to me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh gotcha, nwnw, I did have the same question while I was working on it.

So when we change the compression type, it doesn't require re-encoding of the existing data because each block or SST file includes metadata specifying the compression algorithm used for that particular block or file. This allows RocksDB to understand how to decompress the data regardless of the global compression settings at any given time.

However, compression level, unlike compression types, which are recorded and recognized on a per-block or per-file basis, the specific level detail isn't stored with each block or file. Therefore, if we want to change it, it will require re-encoding everything, which is a huge overhead. I think that's the reason why RocksDB doesn't allow us to dynamically SetOption() for it.

Ref: https://github.com/facebook/rocksdb/wiki/Compression (The first line explains a bit about the granularity of encoding block)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rocksdb don't have this interface is fair enough, however, I don't think changing the level need re-encoding. And decompress block also doesn't need the level

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides, maybe refer to facebook/rocksdb#6615 helps.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see I see, thank you very much for correcting me and finding the reference!!

{"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
1 change: 1 addition & 0 deletions src/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ struct Config {
int level0_stop_writes_trigger;
int level0_file_num_compaction_trigger;
rocksdb::CompressionType compression;
int compression_level;
bool disable_auto_compactions;
bool enable_blob_files;
int min_blob_size;
Expand Down
1 change: 1 addition & 0 deletions src/storage/storage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ rocksdb::Options Storage::InitRocksDBOptions() {
options.min_write_buffer_number_to_merge = 2;
options.write_buffer_size = config_->rocks_db.write_buffer_size * MiB;
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) {
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 @@ -126,6 +126,7 @@ TEST(Config, GetAndSet) {
{"rocksdb.subkey_block_cache_size", "100"},
{"rocksdb.row_cache_size", "100"},
{"rocksdb.rate_limiter_auto_tuned", "yes"},
{"rocksdb.compression_level", "32767"},
};
for (const auto &iter : immutable_cases) {
s = config.Set(nullptr, iter.first, iter.second);
Expand Down