Initial support for secondary cache in LRUCache (#8271)
Summary: Defined the abstract interface for a secondary cache in include/rocksdb/secondary_cache.h, and updated LRUCacheOptions to take a std::shared_ptr<SecondaryCache>. An item is initially inserted into the LRU (primary) cache. When it ages out and evicted from memory, its inserted into the secondary cache. On a LRU cache miss and successful lookup in the secondary cache, the item is promoted to the LRU cache. Only support synchronous lookup currently. The secondary cache would be used to implement a persistent (flash cache) or compressed cache. Tests: Results from cache_bench and db_bench don't show any regression due to these changes. cache_bench results before and after this change - Command ```./cache_bench -ops_per_thread=10000000 -threads=1``` Before ```Complete in 40.688 s; QPS = 245774``` ```Complete in 40.486 s; QPS = 246996``` ```Complete in 42.019 s; QPS = 237989``` After ```Complete in 40.672 s; QPS = 245869``` ```Complete in 44.622 s; QPS = 224107``` ```Complete in 42.445 s; QPS = 235599``` db_bench results before this change, and with this change + https://github.com/facebook/rocksdb/issues/8213 and https://github.com/facebook/rocksdb/issues/8191 - Commands ```./db_bench --benchmarks="fillseq,compact" -num=30000000 -key_size=32 -value_size=256 -use_direct_io_for_flush_and_compaction=true -db=/home/anand76/nvm_cache/db -partition_index_and_filters=true``` ```./db_bench -db=/home/anand76/nvm_cache/db -use_existing_db=true -benchmarks=readrandom -num=30000000 -key_size=32 -value_size=256 -use_direct_reads=true -cache_size=1073741824 -cache_numshardbits=6 -cache_index_and_filter_blocks=true -read_random_exp_range=17 -statistics -partition_index_and_filters=true -threads=16 -duration=300``` Before ``` DB path: [/home/anand76/nvm_cache/db] readrandom : 80.702 micros/op 198104 ops/sec; 54.4 MB/s (3708999 of 3708999 found) ``` ``` DB path: [/home/anand76/nvm_cache/db] readrandom : 87.124 micros/op 183625 ops/sec; 50.4 MB/s (3439999 of 3439999 found) ``` After ``` DB path: [/home/anand76/nvm_cache/db] readrandom : 77.653 micros/op 206025 ops/sec; 56.6 MB/s (3866999 of 3866999 found) ``` ``` DB path: [/home/anand76/nvm_cache/db] readrandom : 84.962 micros/op 188299 ops/sec; 51.7 MB/s (3535999 of 3535999 found) ``` Pull Request resolved: https://github.com/facebook/rocksdb/pull/8271 Reviewed By: zhichao-cao Differential Revision: D28357511 Pulled By: anand1976 fbshipit-source-id: d1cfa236f00e649a18c53328be10a8062a4b6da2main
parent
d15fbae449
commit
feb06e83b2
@ -0,0 +1,77 @@ |
||||
// Copyright (c) 2021, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under both the GPLv2 (found in the
|
||||
// COPYING file in the root directory) and Apache 2.0 License
|
||||
// (found in the LICENSE.Apache file in the root directory).
|
||||
#pragma once |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include <memory> |
||||
#include <string> |
||||
|
||||
#include "rocksdb/cache.h" |
||||
#include "rocksdb/slice.h" |
||||
#include "rocksdb/statistics.h" |
||||
#include "rocksdb/status.h" |
||||
|
||||
namespace ROCKSDB_NAMESPACE { |
||||
|
||||
// A handle for lookup result. The handle may not be immediately ready or
|
||||
// have a valid value. The caller must call isReady() to determine if its
|
||||
// ready, and call Wait() in order to block until it becomes ready.
|
||||
// The caller must call value() after it becomes ready to determine if the
|
||||
// handle successfullly read the item.
|
||||
class SecondaryCacheHandle { |
||||
public: |
||||
virtual ~SecondaryCacheHandle() {} |
||||
|
||||
// Returns whether the handle is ready or not
|
||||
virtual bool IsReady() = 0; |
||||
|
||||
// Block until handle becomes ready
|
||||
virtual void Wait() = 0; |
||||
|
||||
// Return the value. If nullptr, it means the lookup was unsuccessful
|
||||
virtual void* Value() = 0; |
||||
|
||||
// Return the size of value
|
||||
virtual size_t Size() = 0; |
||||
}; |
||||
|
||||
// SecondaryCache
|
||||
//
|
||||
// Cache interface for caching blocks on a secondary tier (which can include
|
||||
// non-volatile media, or alternate forms of caching such as compressed data)
|
||||
class SecondaryCache { |
||||
public: |
||||
virtual ~SecondaryCache() {} |
||||
|
||||
virtual std::string Name() = 0; |
||||
|
||||
// Insert the given value into this cache. The value is not written
|
||||
// directly. Rather, the SaveToCallback provided by helper_cb will be
|
||||
// used to extract the persistable data in value, which will be written
|
||||
// to this tier. The implementation may or may not write it to cache
|
||||
// depending on the admission control policy, even if the return status is
|
||||
// success.
|
||||
virtual Status Insert(const Slice& key, void* value, |
||||
const Cache::CacheItemHelper* helper) = 0; |
||||
|
||||
// Lookup the data for the given key in this cache. The create_cb
|
||||
// will be used to create the object. The handle returned may not be
|
||||
// ready yet, unless wait=true, in which case Lookup() will block until
|
||||
// the handle is ready
|
||||
virtual std::unique_ptr<SecondaryCacheHandle> Lookup( |
||||
const Slice& key, const Cache::CreateCallback& create_cb, bool wait) = 0; |
||||
|
||||
// At the discretion of the implementation, erase the data associated
|
||||
// with key
|
||||
virtual void Erase(const Slice& key) = 0; |
||||
|
||||
// Wait for a collection of handles to become ready
|
||||
virtual void WaitAll(std::vector<SecondaryCacheHandle*> handles) = 0; |
||||
|
||||
virtual std::string GetPrintableOptions() const = 0; |
||||
}; |
||||
|
||||
} // namespace ROCKSDB_NAMESPACE
|
Loading…
Reference in new issue