From 8c0f5b1fcf6d992850cd25cd4d31ebdc9d807ada Mon Sep 17 00:00:00 2001 From: Peter Dillinger Date: Thu, 17 Nov 2022 14:44:59 -0800 Subject: [PATCH] Mark HyperClockCache as production-ready (#10963) Summary: After a couple minor bug fixes and successful productions roll-outs in a few places, I think we can mark this as production-ready. It has a clear value proposition for many workloads, even if we don't have clear advice for every workload yet. Pull Request resolved: https://github.com/facebook/rocksdb/pull/10963 Test Plan: existing tests, comment changes only Reviewed By: siying Differential Revision: D41384083 Pulled By: pdillinger fbshipit-source-id: 56359f01a57bb28de8697666b342382fac72ce6d --- HISTORY.md | 1 + cache/clock_cache.h | 3 ++- include/rocksdb/cache.h | 20 +++++++++++++++----- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 8e024a686f..68e0816bdf 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -15,6 +15,7 @@ * Add basic support for user-defined timestamp to Merge (#10819). * Add stats for ReadAsync time spent and async read errors. * Basic support for the wide-column data model is now available. Wide-column entities can be stored using the `PutEntity` API, and retrieved using `GetEntity` and the new `columns` API of iterator. For compatibility, the classic APIs `Get` and `MultiGet`, as well as iterator's `value` API return the value of the anonymous default column of wide-column entities; also, `GetEntity` and iterator's `columns` return any plain key-values in the form of an entity which only has the anonymous default column. `Merge` (and `GetMergeOperands`) currently also apply to the default column; any other columns of entities are unaffected by `Merge` operations. Note that some features like compaction filters, transactions, user-defined timestamps, and the SST file writer do not yet support wide-column entities; also, there is currently no `MultiGet`-like API to retrieve multiple entities at once. We plan to gradually close the above gaps and also implement new features like column-level operations (e.g. updating or querying only certain columns of an entity). +* Marked HyperClockCache as a production-ready alternative to LRUCache for the block cache. HyperClockCache greatly improves hot-path CPU efficiency under high parallel load or high contention, with some documented caveats and limitations. As much as 4.5x higher ops/sec vs. LRUCache has been seen in db_bench under high parallel load. ### Public API Changes * Marked `block_cache_compressed` as a deprecated feature. Use SecondaryCache instead. diff --git a/cache/clock_cache.h b/cache/clock_cache.h index 21a598ac46..c0be6a5f8d 100644 --- a/cache/clock_cache.h +++ b/cache/clock_cache.h @@ -32,7 +32,8 @@ namespace clock_cache { // Forward declaration of friend class. class ClockCacheTest; -// HyperClockCache is an experimental alternative to LRUCache. +// HyperClockCache is an alternative to LRUCache specifically tailored for +// use as BlockBasedTableOptions::block_cache // // Benefits // -------- diff --git a/include/rocksdb/cache.h b/include/rocksdb/cache.h index ed15e9f981..c3733fb4fb 100644 --- a/include/rocksdb/cache.h +++ b/include/rocksdb/cache.h @@ -287,11 +287,21 @@ extern std::shared_ptr NewCompressedSecondaryCache( extern std::shared_ptr NewCompressedSecondaryCache( const CompressedSecondaryCacheOptions& opts); -// HyperClockCache - EXPERIMENTAL -// -// A lock-free Cache alternative for RocksDB block cache that offers much -// improved CPU efficiency under high parallel load or high contention, with -// some caveats. +// HyperClockCache - A lock-free Cache alternative for RocksDB block cache +// that offers much improved CPU efficiency vs. LRUCache under high parallel +// load or high contention, with some caveats: +// * Not a general Cache implementation: can only be used for +// BlockBasedTableOptions::block_cache, which RocksDB uses in a way that is +// compatible with HyperClockCache. +// * Requires an extra tuning parameter: see estimated_entry_charge below. +// Similarly, substantially changing the capacity with SetCapacity could +// harm efficiency. +// * SecondaryCache is not yet supported. +// * Cache priorities are less aggressively enforced, which could cause +// cache dilution from long range scans (unless they use fill_cache=false). +// * Can be worse for small caches, because if almost all of a cache shard is +// pinned (more likely with non-partitioned filters), then CLOCK eviction +// becomes very CPU intensive. // // See internal cache/clock_cache.h for full description. struct HyperClockCacheOptions : public ShardedCacheOptions {