From 875a9dfed832ca77322defd822a4526b01c71d94 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Wed, 12 Dec 2018 13:41:11 -0600 Subject: [PATCH] common/PriorityCache: Automatic chunk sizing Signed-off-by: Mark Nelson --- src/common/PriorityCache.cc | 36 ++++++++++++++++++++++++++++++----- src/common/PriorityCache.h | 22 ++++++++++++--------- src/common/options.cc | 5 ----- src/kv/KeyValueDB.h | 6 +++++- src/kv/RocksDBStore.cc | 21 +++++++++----------- src/kv/RocksDBStore.h | 5 ++++- src/os/bluestore/BlueStore.cc | 20 ++++++++++++------- src/os/bluestore/BlueStore.h | 16 ++++++++++------ 8 files changed, 85 insertions(+), 46 deletions(-) diff --git a/src/common/PriorityCache.cc b/src/common/PriorityCache.cc index d62e61cc637..cbcf174304a 100644 --- a/src/common/PriorityCache.cc +++ b/src/common/PriorityCache.cc @@ -15,12 +15,38 @@ #include "PriorityCache.h" namespace PriorityCache { - int64_t get_chunk(uint64_t usage, uint64_t chunk_bytes) { - // Add a chunk of headroom and round up to the near chunk - uint64_t val = usage + chunk_bytes; - uint64_t r = (val) % chunk_bytes; + int64_t get_chunk(uint64_t usage, uint64_t total_bytes) { + uint64_t chunk = total_bytes; + + // Find the nearest power of 2 + chunk -= 1; + chunk |= chunk >> 1; + chunk |= chunk >> 2; + chunk |= chunk >> 4; + chunk |= chunk >> 8; + chunk |= chunk >> 16; + chunk |= chunk >> 32; + chunk += 1; + // shrink it to 1/256 of the rounded up cache size + chunk /= 256; + + // bound the chunk size to be between 4MB and 32MB + chunk = (chunk > 4ul*1024*1024) ? chunk : 4ul*1024*1024; + chunk = (chunk < 16ul*1024*1024) ? chunk : 16ul*1024*1024; + + /* Add 16 chunks of headroom and round up to the near chunk. Note that + * if RocksDB is used, it's a good idea to have N MB of headroom where + * N is the target_file_size_base value. RocksDB will read SST files + * into the block cache during compaction which potentially can force out + * all existing cached data. Once compaction is finished, the SST data is + * released leaving an empty cache. Having enough headroom to absorb + * compaction reads allows the kv cache grow even during extremely heavy + * compaction workloads. + */ + uint64_t val = usage + (16 * chunk); + uint64_t r = (val) % chunk; if (r > 0) - val = val + chunk_bytes - r; + val = val + chunk - r; return val; } diff --git a/src/common/PriorityCache.h b/src/common/PriorityCache.h index c31f896e5de..8dcb3e03a7c 100644 --- a/src/common/PriorityCache.h +++ b/src/common/PriorityCache.h @@ -27,18 +27,15 @@ namespace PriorityCache { LAST = PRI3, }; - int64_t get_chunk(uint64_t usage, uint64_t chunk_bytes); + int64_t get_chunk(uint64_t usage, uint64_t total_bytes); struct PriCache { virtual ~PriCache(); - /* Ask the cache to request memory for the given priority rounded up to - * the nearst chunk_bytes. This for example, may return the size of all - * items associated with this priority plus some additional space for - * future growth. Note that the cache may ultimately be allocated less - * memory than it requests here. + /* Ask the cache to request memory for the given priority. Note that the + * cache may ultimately be allocated less memory than it requests here. */ - virtual int64_t request_cache_bytes(PriorityCache::Priority pri, uint64_t chunk_bytes) const = 0; + virtual int64_t request_cache_bytes(PriorityCache::Priority pri, uint64_t total_cache) const = 0; // Get the number of bytes currently allocated to the given priority. virtual int64_t get_cache_bytes(PriorityCache::Priority pri) const = 0; @@ -52,8 +49,15 @@ namespace PriorityCache { // Allocate additional bytes for a given priority. virtual void add_cache_bytes(PriorityCache::Priority pri, int64_t bytes) = 0; - // Commit the current number of bytes allocated to the cache. - virtual int64_t commit_cache_size() = 0; + /* Commit the current number of bytes allocated to the cache. Space is + * allocated in chunks based on the allocation size and current total size + * of memory available for caches. */ + virtual int64_t commit_cache_size(uint64_t total_cache) = 0; + + /* Get the current number of bytes allocated to the cache. this may be + * larger than the value returned by get_cache_bytes as it includes extra + * space for future growth. */ + virtual int64_t get_committed_size() const = 0; // Get the ratio of available memory this cache should target. virtual double get_cache_ratio() const = 0; diff --git a/src/common/options.cc b/src/common/options.cc index 2ed6e83f71b..23ab5de3c07 100644 --- a/src/common/options.cc +++ b/src/common/options.cc @@ -4185,11 +4185,6 @@ std::vector