Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support of using hyper clock cache as the block cache #2031

Merged
merged 15 commits into from
Jan 24, 2024
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
11 changes: 11 additions & 0 deletions kvrocks.conf
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,17 @@ migrate-sequence-gap 10000
# Default: 4096MB
rocksdb.block_cache_size 4096

# Specify the type of cache used in the block cache.
# Accept value: "lru", "hcc"
# "lru" stands for the cache with the LRU(Least Recently Used) replacement policy.
#
# "hcc" stands for the Hyper Clock Cache, a lock-free cache alternative
# that offers much improved CPU efficiency vs. LRU cache under high parallel
# load or high contention.
#
# default lru
rocksdb.block_cache_type lru

# A global cache for table-level rows in RocksDB. If almost always point
# lookups, enlarging row cache may improve read performance. Otherwise,
# if we enlarge this value, we can lessen metadata/subkey block cache size.
Expand Down
11 changes: 11 additions & 0 deletions src/config/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ const std::vector<ConfigEnum<rocksdb::CompressionType>> compression_types{[] {
return res;
}()};

const std::vector<ConfigEnum<BlockCacheType>> cache_types{[] {
std::vector<ConfigEnum<BlockCacheType>> res;
res.reserve(engine::CacheOptions.size());
for (const auto &e : engine::CacheOptions) {
res.push_back({e.name, e.type});
}
return res;
}()};

std::string TrimRocksDbPrefix(std::string s) {
if (strncasecmp(s.data(), "rocksdb.", 8) != 0) return s;
return s.substr(8, s.size() - 8);
Expand Down Expand Up @@ -191,6 +200,8 @@ Config::Config() {
{"rocksdb.stats_dump_period_sec", false, new IntField(&rocks_db.stats_dump_period_sec, 0, 0, INT_MAX)},
{"rocksdb.cache_index_and_filter_blocks", true, new YesNoField(&rocks_db.cache_index_and_filter_blocks, true)},
{"rocksdb.block_cache_size", true, new IntField(&rocks_db.block_cache_size, 0, 0, INT_MAX)},
{"rocksdb.block_cache_type", true,
new EnumField<BlockCacheType>(&rocks_db.block_cache_type, cache_types, BlockCacheType::kCacheTypeLRU)},
{"rocksdb.subkey_block_cache_size", true, new IntField(&rocks_db.subkey_block_cache_size, 2048, 0, INT_MAX)},
{"rocksdb.metadata_block_cache_size", true, new IntField(&rocks_db.metadata_block_cache_size, 2048, 0, INT_MAX)},
{"rocksdb.share_metadata_and_subkey_block_cache", true,
Expand Down
3 changes: 3 additions & 0 deletions src/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ constexpr const uint32_t kDefaultPort = 6666;

constexpr const char *kDefaultNamespace = "__namespace";

enum class BlockCacheType { kCacheTypeLRU = 0, kCacheTypeHCC };

struct CompactionCheckerRange {
public:
int start;
Expand Down Expand Up @@ -169,6 +171,7 @@ struct Config {
int block_size;
bool cache_index_and_filter_blocks;
int block_cache_size;
BlockCacheType block_cache_type;
int metadata_block_cache_size;
int subkey_block_cache_size;
bool share_metadata_and_subkey_block_cache;
Expand Down
33 changes: 31 additions & 2 deletions src/storage/storage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "event_util.h"
#include "redis_db.h"
#include "redis_metadata.h"
#include "rocksdb/cache.h"
#include "rocksdb_crc32c.h"
#include "server/server.h"
#include "table_properties_collector.h"
Expand All @@ -52,6 +53,23 @@ namespace engine {

constexpr const char *kReplicationIdKey = "replication_id_";

// used in creating rocksdb::LRUCache, set `num_shard_bits` to -1 means let rocksdb choose a good default shard count
// based on the capacity and the implementation.
constexpr int kRocksdbLRUAutoAdjustShardBits = -1;

// used as the default argument for `strict_capacity_limit` in creating rocksdb::Cache.
constexpr bool kRocksdbCacheStrictCapacityLimit = false;

// used as the default argument for `high_pri_pool_ratio` in creating block cache.
constexpr double kRocksdbLRUBlockCacheHighPriPoolRatio = 0.75;

// used as the default argument for `high_pri_pool_ratio` in creating row cache.
constexpr double kRocksdbLRURowCacheHighPriPoolRatio = 0.5;

// used in creating rocksdb::HyperClockCache, set`estimated_entry_charge` to 0 means let rocksdb dynamically and
// automacally adjust the table size for the cache.
constexpr size_t kRockdbHCCAutoAdjustCharge = 0;

const int64_t kIORateLimitMaxMb = 1024000;

using rocksdb::Slice;
Expand Down Expand Up @@ -152,9 +170,12 @@ rocksdb::Options Storage::InitRocksDBOptions() {
options.compression_per_level[i] = config_->rocks_db.compression;
}
}

if (config_->rocks_db.row_cache_size) {
options.row_cache = rocksdb::NewLRUCache(config_->rocks_db.row_cache_size * MiB);
options.row_cache = rocksdb::NewLRUCache(config_->rocks_db.row_cache_size * MiB, kRocksdbLRUAutoAdjustShardBits,
kRocksdbCacheStrictCapacityLimit, kRocksdbLRURowCacheHighPriPoolRatio);
}

options.enable_pipelined_write = config_->rocks_db.enable_pipelined_write;
options.target_file_size_base = config_->rocks_db.target_file_size_base * MiB;
options.max_manifest_file_size = 64 * MiB;
Expand Down Expand Up @@ -256,7 +277,15 @@ Status Storage::Open(DBOpenMode mode) {
}
}

std::shared_ptr<rocksdb::Cache> shared_block_cache = rocksdb::NewLRUCache(block_cache_size, -1, false, 0.75);
std::shared_ptr<rocksdb::Cache> shared_block_cache;

if (config_->rocks_db.block_cache_type == BlockCacheType::kCacheTypeLRU) {
shared_block_cache = rocksdb::NewLRUCache(block_cache_size, kRocksdbLRUAutoAdjustShardBits,
kRocksdbCacheStrictCapacityLimit, kRocksdbLRUBlockCacheHighPriPoolRatio);
} else {
rocksdb::HyperClockCacheOptions hcc_cache_options(block_cache_size, kRockdbHCCAutoAdjustCharge);
shared_block_cache = hcc_cache_options.MakeSharedCache();
}

rocksdb::BlockBasedTableOptions metadata_table_opts = InitTableOptions();
metadata_table_opts.block_cache = shared_block_cache;
Expand Down
11 changes: 11 additions & 0 deletions src/storage/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ inline const std::vector<CompressionOption> CompressionOptions = {
{rocksdb::kZSTD, "zstd", "kZSTD"},
};

struct CacheOption {
BlockCacheType type;
const std::string name;
const std::string val;
};

inline const std::vector<CacheOption> CacheOptions = {
{BlockCacheType::kCacheTypeLRU, "lru", "kCacheTypeLRU"},
{BlockCacheType::kCacheTypeHCC, "hcc", "kCacheTypeHCC"},
};

enum class StatType {
CompactionCount,
FlushCount,
Expand Down