From 4118e13330b70ea5d1648e77c9c28704bc2be411 Mon Sep 17 00:00:00 2001 From: Karthikeyan Radhakrishnan Date: Mon, 21 Nov 2016 17:22:01 -0800 Subject: [PATCH] Persistent Cache: Expose stats to user via public API Summary: Exposing persistent cache stats (counters) to the user via public API. Closes https://github.com/facebook/rocksdb/pull/1485 Differential Revision: D4155274 Pulled By: siying fbshipit-source-id: 30a9f50 --- db/db_test2.cc | 4 ++ include/rocksdb/persistent_cache.h | 8 +++ .../persistent_cache/block_cache_tier.cc | 64 +++++++++++-------- utilities/persistent_cache/block_cache_tier.h | 6 +- .../persistent_cache/persistent_cache_test.cc | 2 + .../persistent_cache/persistent_cache_tier.cc | 17 +++-- .../persistent_cache/persistent_cache_tier.h | 6 +- .../persistent_cache/volatile_tier_impl.cc | 27 ++------ .../persistent_cache/volatile_tier_impl.h | 5 +- 9 files changed, 72 insertions(+), 67 deletions(-) diff --git a/db/db_test2.cc b/db/db_test2.cc index 50a1e6212..e3148ef5c 100644 --- a/db/db_test2.cc +++ b/db/db_test2.cc @@ -1470,6 +1470,10 @@ class MockPersistentCache : public PersistentCache { virtual ~MockPersistentCache() {} + PersistentCache::StatsType Stats() override { + return PersistentCache::StatsType(); + } + Status Insert(const Slice& page_key, const char* data, const size_t size) override { MutexLock _(&lock_); diff --git a/include/rocksdb/persistent_cache.h b/include/rocksdb/persistent_cache.h index 8d01fa1bd..f93139736 100644 --- a/include/rocksdb/persistent_cache.h +++ b/include/rocksdb/persistent_cache.h @@ -24,6 +24,8 @@ namespace rocksdb { // cache interface is specifically designed for persistent read cache. class PersistentCache { public: + typedef std::vector> StatsType; + virtual ~PersistentCache() {} // Insert to page cache @@ -46,6 +48,12 @@ class PersistentCache { // // True if the cache is configured to store uncompressed data else false virtual bool IsCompressed() = 0; + + // Return stats as map of {string, double} per-tier + // + // Persistent cache can be initialized as a tier of caches. The stats are per + // tire top-down + virtual StatsType Stats() = 0; }; // Factor method to create a new persistent cache diff --git a/utilities/persistent_cache/block_cache_tier.cc b/utilities/persistent_cache/block_cache_tier.cc index 49a70174c..49c41c38b 100644 --- a/utilities/persistent_cache/block_cache_tier.cc +++ b/utilities/persistent_cache/block_cache_tier.cc @@ -123,34 +123,42 @@ Status BlockCacheTier::Close() { return Status::OK(); } -std::string BlockCacheTier::PrintStats() { - std::ostringstream os; - os << "persistentcache.blockcachetier.bytes_piplined: " - << stats_.bytes_pipelined_.ToString() << std::endl - << "persistentcache.blockcachetier.bytes_written: " - << stats_.bytes_written_.ToString() << std::endl - << "persistentcache.blockcachetier.bytes_read: " - << stats_.bytes_read_.ToString() << std::endl - << "persistentcache.blockcachetier.insert_dropped" - << stats_.insert_dropped_ << std::endl - << "persistentcache.blockcachetier.cache_hits: " << stats_.cache_hits_ - << std::endl - << "persistentcache.blockcachetier.cache_misses: " << stats_.cache_misses_ - << std::endl - << "persistentcache.blockcachetier.cache_errors: " << stats_.cache_errors_ - << std::endl - << "persistentcache.blockcachetier.cache_hits_pct: " - << stats_.CacheHitPct() << std::endl - << "persistentcache.blockcachetier.cache_misses_pct: " - << stats_.CacheMissPct() << std::endl - << "persistentcache.blockcachetier.read_hit_latency: " - << stats_.read_hit_latency_.ToString() << std::endl - << "persistentcache.blockcachetier.read_miss_latency: " - << stats_.read_miss_latency_.ToString() << std::endl - << "persistenetcache.blockcachetier.write_latency: " - << stats_.write_latency_.ToString() << std::endl - << PersistentCacheTier::PrintStats(); - return os.str(); +template +void Add(std::map* stats, const std::string& key, + const T& t) { + stats->insert({key, static_cast(t)}); +} + +PersistentCache::StatsType BlockCacheTier::Stats() { + std::map stats; + Add(&stats, "persistentcache.blockcachetier.bytes_piplined", + stats_.bytes_pipelined_.Average()); + Add(&stats, "persistentcache.blockcachetier.bytes_written", + stats_.bytes_written_.Average()); + Add(&stats, "persistentcache.blockcachetier.bytes_read", + stats_.bytes_read_.Average()); + Add(&stats, "persistentcache.blockcachetier.insert_dropped", + stats_.insert_dropped_); + Add(&stats, "persistentcache.blockcachetier.cache_hits", + stats_.cache_hits_); + Add(&stats, "persistentcache.blockcachetier.cache_misses", + stats_.cache_misses_); + Add(&stats, "persistentcache.blockcachetier.cache_errors", + stats_.cache_errors_); + Add(&stats, "persistentcache.blockcachetier.cache_hits_pct", + stats_.CacheHitPct()); + Add(&stats, "persistentcache.blockcachetier.cache_misses_pct", + stats_.CacheMissPct()); + Add(&stats, "persistentcache.blockcachetier.read_hit_latency", + stats_.read_hit_latency_.Average()); + Add(&stats, "persistentcache.blockcachetier.read_miss_latency", + stats_.read_miss_latency_.Average()); + Add(&stats, "persistenetcache.blockcachetier.write_latency", + stats_.write_latency_.Average()); + + auto out = PersistentCacheTier::Stats(); + out.push_back(stats); + return out; } Status BlockCacheTier::Insert(const Slice& key, const char* data, diff --git a/utilities/persistent_cache/block_cache_tier.h b/utilities/persistent_cache/block_cache_tier.h index 9330d0538..257024760 100644 --- a/utilities/persistent_cache/block_cache_tier.h +++ b/utilities/persistent_cache/block_cache_tier.h @@ -64,7 +64,7 @@ class BlockCacheTier : public PersistentCacheTier { bool IsCompressed() override { return opt_.is_compressed; } - std::string PrintStats() override; + PersistentCache::StatsType Stats() override; void TEST_Flush() override { while (insert_ops_.Size()) { @@ -110,7 +110,7 @@ class BlockCacheTier : public PersistentCacheTier { Status CleanupCacheFolder(const std::string& folder); // Statistics - struct Stats { + struct Statistics { HistogramImpl bytes_pipelined_; HistogramImpl bytes_written_; HistogramImpl bytes_read_; @@ -143,7 +143,7 @@ class BlockCacheTier : public PersistentCacheTier { ThreadedWriter writer_; // Writer threads BlockCacheTierMetadata metadata_; // Cache meta data manager std::atomic size_{0}; // Size of the cache - Stats stats_; // Statistics + Statistics stats_; // Statistics }; } // namespace rocksdb diff --git a/utilities/persistent_cache/persistent_cache_test.cc b/utilities/persistent_cache/persistent_cache_test.cc index 0d8ab6971..42ef6bde1 100644 --- a/utilities/persistent_cache/persistent_cache_test.cc +++ b/utilities/persistent_cache/persistent_cache_test.cc @@ -244,6 +244,8 @@ TEST_F(PersistentCacheTierTest, FactoryTest) { /*size=*/1 * 1024 * 1024 * 1024, log, nvm_opt, &cache)); ASSERT_TRUE(cache); + ASSERT_EQ(cache->Stats().size(), 1); + ASSERT_TRUE(cache->Stats()[0].size()); cache.reset(); } } diff --git a/utilities/persistent_cache/persistent_cache_tier.cc b/utilities/persistent_cache/persistent_cache_tier.cc index 889d9e9fc..fde3c4a70 100644 --- a/utilities/persistent_cache/persistent_cache_tier.cc +++ b/utilities/persistent_cache/persistent_cache_tier.cc @@ -8,6 +8,7 @@ #include "utilities/persistent_cache/persistent_cache_tier.h" #include +#include namespace rocksdb { @@ -40,17 +41,21 @@ bool PersistentCacheTier::Erase(const Slice& key) { } std::string PersistentCacheTier::PrintStats() { - if (next_tier_) { - return next_tier_->PrintStats(); + std::ostringstream os; + for (auto tier_stats : Stats()) { + os << "---- next tier -----" << std::endl; + for (auto stat : tier_stats) { + os << stat.first << ": " << stat.second << std::endl; + } } - return std::string(); + return os.str(); } -std::vector PersistentCacheTier::Stats() { +PersistentCache::StatsType PersistentCacheTier::Stats() { if (next_tier_) { return next_tier_->Stats(); } - return std::vector{}; + return PersistentCache::StatsType{}; } // @@ -77,7 +82,7 @@ bool PersistentTieredCache::Erase(const Slice& key) { return tiers_.front()->Erase(key); } -std::vector PersistentTieredCache::Stats() { +PersistentCache::StatsType PersistentTieredCache::Stats() { assert(!tiers_.empty()); return tiers_.front()->Stats(); } diff --git a/utilities/persistent_cache/persistent_cache_tier.h b/utilities/persistent_cache/persistent_cache_tier.h index 64ec3ae67..af0395f27 100644 --- a/utilities/persistent_cache/persistent_cache_tier.h +++ b/utilities/persistent_cache/persistent_cache_tier.h @@ -231,7 +231,6 @@ struct PersistentCacheConfig { class PersistentCacheTier : public PersistentCache { public: typedef std::shared_ptr Tier; - typedef std::map TierStats; virtual ~PersistentCacheTier() {} @@ -250,8 +249,7 @@ class PersistentCacheTier : public PersistentCache { // Print stats to string recursively virtual std::string PrintStats(); - // Expose stats - virtual std::vector Stats(); + virtual PersistentCache::StatsType Stats(); // Insert to page cache virtual Status Insert(const Slice& page_key, const char* data, @@ -296,7 +294,7 @@ class PersistentTieredCache : public PersistentCacheTier { Status Close() override; bool Erase(const Slice& key) override; std::string PrintStats() override; - std::vector Stats() override; + PersistentCache::StatsType Stats() override; Status Insert(const Slice& page_key, const char* data, const size_t size) override; Status Lookup(const Slice& page_key, std::unique_ptr* data, diff --git a/utilities/persistent_cache/volatile_tier_impl.cc b/utilities/persistent_cache/volatile_tier_impl.cc index aca9fcaf5..fad8cbe68 100644 --- a/utilities/persistent_cache/volatile_tier_impl.cc +++ b/utilities/persistent_cache/volatile_tier_impl.cc @@ -18,8 +18,8 @@ void VolatileCacheTier::DeleteCacheData(VolatileCacheTier::CacheData* data) { VolatileCacheTier::~VolatileCacheTier() { index_.Clear(&DeleteCacheData); } -std::vector VolatileCacheTier::Stats() { - PersistentCacheTier::TierStats stat; +PersistentCache::StatsType VolatileCacheTier::Stats() { + std::map stat; stat.insert({"persistent_cache.volatile_cache.hits", static_cast(stats_.cache_hits_)}); stat.insert({"persistent_cache.volatile_cache.misses", @@ -33,26 +33,9 @@ std::vector VolatileCacheTier::Stats() { stat.insert({"persistent_cache.volatile_cache.miss_pct", static_cast(stats_.CacheMissPct())}); - std::vector tier_stats; - if (next_tier()) { - tier_stats = next_tier()->Stats(); - } - tier_stats.push_back(stat); - return tier_stats; -} - -std::string VolatileCacheTier::PrintStats() { - std::ostringstream ss; - ss << "pagecache.volatilecache.hits: " << stats_.cache_hits_ << std::endl - << "pagecache.volatilecache.misses: " << stats_.cache_misses_ << std::endl - << "pagecache.volatilecache.inserts: " << stats_.cache_inserts_ - << std::endl - << "pagecache.volatilecache.evicts: " << stats_.cache_evicts_ << std::endl - << "pagecache.volatilecache.hit_pct: " << stats_.CacheHitPct() << std::endl - << "pagecache.volatilecache.miss_pct: " << stats_.CacheMissPct() - << std::endl - << PersistentCacheTier::PrintStats(); - return ss.str(); + auto out = PersistentCacheTier::Stats(); + out.push_back(stat); + return out; } Status VolatileCacheTier::Insert(const Slice& page_key, const char* data, diff --git a/utilities/persistent_cache/volatile_tier_impl.h b/utilities/persistent_cache/volatile_tier_impl.h index a29c4ac30..3f914dd79 100644 --- a/utilities/persistent_cache/volatile_tier_impl.h +++ b/utilities/persistent_cache/volatile_tier_impl.h @@ -63,10 +63,7 @@ class VolatileCacheTier : public PersistentCacheTier { bool Erase(const Slice& key) override; // Expose stats as map - std::vector Stats() override; - - // Print stats to string - std::string PrintStats() override; + PersistentCache::StatsType Stats() override; private: //