diff --git a/cachelib/allocator/BackgroundEvictor-inl.h b/cachelib/allocator/BackgroundEvictor-inl.h index a0f8c9b299..bdf72be209 100644 --- a/cachelib/allocator/BackgroundEvictor-inl.h +++ b/cachelib/allocator/BackgroundEvictor-inl.h @@ -39,10 +39,11 @@ void BackgroundEvictor::work() { while (auto entry = tasks_.try_dequeue()) { auto [pid, cid] = entry.value(); auto batch = strategy_->calculateBatchSize(cache_, tid_, pid, cid); + stats.evictionSize.add(batch); auto evicted = BackgroundEvictorAPIWrapper::traverseAndEvictItems(cache_, tid_,pid,cid,batch); - numEvictedItemsFromSchedule_.fetch_add(1, std::memory_order_relaxed); - runCount_.fetch_add(1, std::memory_order_relaxed); + stats.numEvictedItemsFromSchedule.inc(); + stats.numTraversals.inc(); } } else { for (const auto pid : cache_.getRegularPoolIds()) { @@ -71,10 +72,12 @@ void BackgroundEvictor::checkAndRun(PoolId pid) { continue; } + stats.evictionSize.add(batch); //try evicting BATCH items from the class in order to reach free target auto evicted = BackgroundEvictorAPIWrapper::traverseAndEvictItems(cache_, tid_,pid,cid,batch); + evictions += evicted; const size_t cid_id = (size_t)mpStats.acStats.at(cid).allocSize; auto it = evictions_per_class_.find(cid_id); @@ -84,19 +87,21 @@ void BackgroundEvictor::checkAndRun(PoolId pid) { evictions_per_class_[cid_id] = 0; } } - runCount_.fetch_add(1, std::memory_order_relaxed); - numEvictedItems_.fetch_add(evictions, std::memory_order_relaxed); - totalClasses_.fetch_add(classes, std::memory_order_relaxed); + stats.numEvictedItems.add(evictions); + stats.numClasses.add(classes); + stats.numTraversals.inc(); } template -BackgroundEvictorStats BackgroundEvictor::getStats() const noexcept { - BackgroundEvictorStats stats; - stats.numEvictedItems = numEvictedItems_.load(std::memory_order_relaxed); - stats.runCount = runCount_.load(std::memory_order_relaxed); - stats.numEvictedItemsFromSchedule = numEvictedItemsFromSchedule_.load(std::memory_order_relaxed); - stats.totalClasses = totalClasses_.load(std::memory_order_relaxed); - return stats; +BackgroundEvictionStats BackgroundEvictor::getStats() const noexcept { + BackgroundEvictionStats evicStats; + evicStats.numEvictedItems = stats.numEvictedItems.get(); + evicStats.numEvictedItemsFromSchedule = stats.numEvictedItemsFromSchedule.get(); + evicStats.numTraversals = stats.numTraversals.get(); + evicStats.numClasses = stats.numClasses.get(); + evicStats.evictionSize = stats.evictionSize.get(); + + return evicStats; } template diff --git a/cachelib/allocator/BackgroundEvictor.h b/cachelib/allocator/BackgroundEvictor.h index 3d8ac3a4cc..7cecb04ba1 100644 --- a/cachelib/allocator/BackgroundEvictor.h +++ b/cachelib/allocator/BackgroundEvictor.h @@ -22,6 +22,7 @@ #include "cachelib/allocator/CacheStats.h" #include "cachelib/common/PeriodicWorker.h" #include "cachelib/allocator/BackgroundEvictorStrategy.h" +#include "cachelib/common/AtomicCounter.h" namespace facebook { @@ -38,6 +39,23 @@ struct BackgroundEvictorAPIWrapper { } }; +struct BackgroundEvictorStats { + // items evicted + AtomicCounter numEvictedItems{0}; + + // items evicted from schedule + AtomicCounter numEvictedItemsFromSchedule; + + // traversals + AtomicCounter numTraversals{0}; + + // total number of classes + AtomicCounter numClasses{0}; + + // item eviction size + AtomicCounter evictionSize{0}; +}; + // Periodic worker that evicts items from tiers in batches // The primary aim is to reduce insertion times for new items in the // cache @@ -58,7 +76,9 @@ class BackgroundEvictor : public PeriodicWorker { void schedule(size_t pid, size_t cid) { tasks_.enqueue(std::make_pair(pid,cid)); } - BackgroundEvictorStats getStats() const noexcept; + + BackgroundEvictionStats getStats() const noexcept; + std::map getClassStats() const noexcept; private: @@ -74,12 +94,10 @@ class BackgroundEvictor : public PeriodicWorker { // implements the actual logic of running the background evictor void work() override final; void checkAndRun(PoolId pid); - + + BackgroundEvictorStats stats; + std::map evictions_per_class_; - std::atomic numEvictedItems_{0}; - std::atomic numEvictedItemsFromSchedule_{0}; - std::atomic runCount_{0}; - std::atomic totalClasses_{0}; }; } // namespace cachelib } // namespace facebook diff --git a/cachelib/allocator/CacheAllocator-inl.h b/cachelib/allocator/CacheAllocator-inl.h index 0761b0a7c6..297fc29f35 100644 --- a/cachelib/allocator/CacheAllocator-inl.h +++ b/cachelib/allocator/CacheAllocator-inl.h @@ -3676,7 +3676,7 @@ GlobalCacheStats CacheAllocator::getGlobalCacheStats() const { ret.nvmCacheEnabled = nvmCache_ ? nvmCache_->isEnabled() : false; ret.nvmUpTime = currTime - getNVMCacheCreationTime(); ret.reaperStats = getReaperStats(); - ret.backgroundEvictorStats = getBackgroundEvictorStats(); + ret.evictionStats = getBackgroundEvictorStats(); ret.numActiveHandles = getNumActiveHandles(); return ret; diff --git a/cachelib/allocator/CacheAllocator.h b/cachelib/allocator/CacheAllocator.h index d69a753f4a..4e62d34923 100644 --- a/cachelib/allocator/CacheAllocator.h +++ b/cachelib/allocator/CacheAllocator.h @@ -1044,8 +1044,8 @@ class CacheAllocator : public CacheBase { } // returns the background evictor - BackgroundEvictorStats getBackgroundEvictorStats() const { - auto stats = backgroundEvictor_ ? backgroundEvictor_->getStats() : BackgroundEvictorStats{}; + BackgroundEvictionStats getBackgroundEvictorStats() const { + auto stats = backgroundEvictor_ ? backgroundEvictor_->getStats() : BackgroundEvictionStats{}; return stats; } diff --git a/cachelib/allocator/CacheStats.h b/cachelib/allocator/CacheStats.h index 1a290e2674..0e48d55aa9 100644 --- a/cachelib/allocator/CacheStats.h +++ b/cachelib/allocator/CacheStats.h @@ -285,8 +285,8 @@ struct ReaperStats { uint64_t avgTraversalTimeMs{0}; }; -// Stats for background evictor -struct BackgroundEvictorStats { +// Eviction Stats +struct BackgroundEvictionStats { // the number of items this worker evicted by looking at pools/classes stats uint64_t numEvictedItems{0}; @@ -294,12 +294,13 @@ struct BackgroundEvictorStats { uint64_t numEvictedItemsFromSchedule{0}; // number of times we went executed the thread //TODO: is this def correct? - uint64_t runCount{0}; - - uint64_t totalClasses{0}; - + uint64_t numTraversals{0}; + // total number of classes + uint64_t numClasses{0}; + // eviction size + uint64_t evictionSize{0}; }; // CacheMetadata type to export @@ -322,6 +323,9 @@ struct Stats; // Stats that apply globally in cache and // the ones that are aggregated over all pools struct GlobalCacheStats { + // background eviction stats + BackgroundEvictionStats evictionStats; + // number of calls to CacheAllocator::find uint64_t numCacheGets{0}; @@ -486,9 +490,6 @@ struct GlobalCacheStats { // stats related to the reaper ReaperStats reaperStats; - - // stats related to the background evictor - BackgroundEvictorStats backgroundEvictorStats; uint64_t numNvmRejectsByExpiry{}; uint64_t numNvmRejectsByClean{}; diff --git a/cachelib/cachebench/cache/Cache-inl.h b/cachelib/cachebench/cache/Cache-inl.h index 538bb2b73c..cff0b39b11 100644 --- a/cachelib/cachebench/cache/Cache-inl.h +++ b/cachelib/cachebench/cache/Cache-inl.h @@ -527,14 +527,29 @@ Stats Cache::getStats() const { const auto navyStats = cache_->getNvmCacheStatsMap(); Stats ret; + ret.backgndEvicStats.nEvictedItems = + cacheStats.evictionStats.numEvictedItems; + ret.backgndEvicStats.nEvictedItemsFromSchedule = + cacheStats.evictionStats.numEvictedItemsFromSchedule; + ret.backgndEvicStats.nTraversals = + cacheStats.evictionStats.numTraversals; + ret.backgndEvicStats.evictionSize = + cacheStats.evictionStats.evictionSize; + ret.numEvictions = aggregate.numEvictions(); ret.numItems = aggregate.numItems(); ret.allocAttempts = cacheStats.allocAttempts; ret.allocFailures = cacheStats.allocFailures; + + ret.numCacheGets = cacheStats.numCacheGets; + ret.numCacheGetMiss = cacheStats.numCacheGetMiss; + ret.numRamDestructorCalls = cacheStats.numRamDestructorCalls; ret.numBackgroundEvictions = cacheStats.backgroundEvictorStats.numEvictedItems; ret.numBackgroundEvictionsFromSchedule = cacheStats.backgroundEvictorStats.numEvictedItemsFromSchedule; - ret.numBackgroundEvictorRuns = cacheStats.backgroundEvictorStats.runCount; + ret.numBackgroundEvictorRuns = cacheStats.backgroundEvictorStats.numTraversals; + ret.numClasses = cacheStats.backgroundEvictorStats.numClasses; + ret.numNvmGets = cacheStats.numNvmGets; ret.numNvmGetMiss = cacheStats.numNvmGetMiss; ret.numNvmGetCoalesced = cacheStats.numNvmGetCoalesced; diff --git a/cachelib/cachebench/cache/CacheStats.h b/cachelib/cachebench/cache/CacheStats.h index 0de213f9ce..fd20c64737 100644 --- a/cachelib/cachebench/cache/CacheStats.h +++ b/cachelib/cachebench/cache/CacheStats.h @@ -25,18 +25,33 @@ DECLARE_bool(report_api_latency); namespace facebook { namespace cachelib { namespace cachebench { + +struct BackgroundEvictionStats { + // the number of items this worker evicted by looking at pools/classes stats + uint64_t nEvictedItems{0}; + + // the number of items this worker evicted for pools/classes requested by schedule call + uint64_t nEvictedItemsFromSchedule{0}; + + // number of times we went executed the thread //TODO: is this def correct? + uint64_t nTraversals{0}; + + // number of classes searched + uint64_t nClasses{0}; + + // size of evicted items + uint64_t evictionSize; +}; + struct Stats { + BackgroundEvictionStats backgndEvicStats; + uint64_t numEvictions{0}; uint64_t numItems{0}; uint64_t allocAttempts{0}; uint64_t allocFailures{0}; - uint64_t numBackgroundEvictions{0}; - uint64_t numBackgroundEvictionsFromSchedule{0}; - uint64_t numBackgroundEvictorRuns{0}; - uint64_t numBackgroundEvictorClasses{0}; - uint64_t numCacheGets{0}; uint64_t numCacheGetMiss{0}; uint64_t numRamDestructorCalls{0}; @@ -121,14 +136,17 @@ struct Stats { invertPctFn(allocFailures, allocAttempts)) << std::endl; out << folly::sformat("RAM Evictions : {:,}", numEvictions) << std::endl; - - out << folly::sformat("Background Tier 0 Evictions : {:,}", numBackgroundEvictions) << std::endl; - out << folly::sformat("Background Tier 0 Evictions from schedule() : {:,}", numBackgroundEvictionsFromSchedule) << std::endl; - - out << folly::sformat("Background Tier 0 Eviction Runs : {:,}", numBackgroundEvictorRuns) << std::endl; - - out << folly::sformat("Background Tier 0 Total Classes Searched : {:,}", numBackgroundEvictorClasses) << std::endl; + out << folly::sformat("Tier 0 Background Evicted items : {:,}", + backgndEvicStats.nEvictedItems) << std::endl; + out << folly::sformat("Tier 0 Background Evicted items from schedule : {:,}", + backgndEvicStats.nEvictedItemsFromSchedule) << std::endl; + out << folly::sformat("Tier 0 Background Traversals : {:,}", + backgndEvicStats.nTraversals) << std::endl; + out << folly::sformat("Tier 0 Classes searched : {:,}", + backgndEvicStats.nClasses) << std::endl; + out << folly::sformat("Tier 0 Background Evicted Size : {:,}", + backgndEvicStats.evictionSize) << std::endl; if (numCacheGets > 0) { out << folly::sformat("Cache Gets : {:,}", numCacheGets) << std::endl;