Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,37 @@ namespace cachelib {


template <typename CacheT>
BackgroundEvictor<CacheT>::BackgroundEvictor(Cache& cache,
std::shared_ptr<BackgroundEvictorStrategy> strategy)
BackgroundMover<CacheT>::BackgroundMover(Cache& cache,
std::shared_ptr<BackgroundMoverStrategy> strategy,
MoverDir direction)
: cache_(cache),
strategy_(strategy)
strategy_(strategy),
direction_(direction)
{
if (direction_ == MoverDir::Evict) {
moverFunc =
BackgroundMoverAPIWrapper<CacheT>::traverseAndEvictItems;

} else if (direction_ == MoverDir::Promote) {
moverFunc =
BackgroundMoverAPIWrapper<CacheT>::traverseAndPromoteItems;
}
}

template <typename CacheT>
BackgroundEvictor<CacheT>::~BackgroundEvictor() { stop(std::chrono::seconds(0)); }
BackgroundMover<CacheT>::~BackgroundMover() { stop(std::chrono::seconds(0)); }

template <typename CacheT>
void BackgroundEvictor<CacheT>::work() {
void BackgroundMover<CacheT>::work() {
try {
checkAndRun();
} catch (const std::exception& ex) {
XLOGF(ERR, "BackgroundEvictor interrupted due to exception: {}", ex.what());
XLOGF(ERR, "BackgroundMover interrupted due to exception: {}", ex.what());
}
}

template <typename CacheT>
void BackgroundEvictor<CacheT>::setAssignedMemory(std::vector<std::tuple<TierId, PoolId, ClassId>> &&assignedMemory)
void BackgroundMover<CacheT>::setAssignedMemory(std::vector<std::tuple<TierId, PoolId, ClassId>> &&assignedMemory)
{
XLOG(INFO, "Class assigned to background worker:");
for (auto [tid, pid, cid] : assignedMemory) {
Expand All @@ -54,12 +64,12 @@ void BackgroundEvictor<CacheT>::setAssignedMemory(std::vector<std::tuple<TierId,
// Look for classes that exceed the target memory capacity
// and return those for eviction
template <typename CacheT>
void BackgroundEvictor<CacheT>::checkAndRun() {
void BackgroundMover<CacheT>::checkAndRun() {
auto assignedMemory = mutex.lock_combine([this]{
return assignedMemory_;
});

unsigned int evictions = 0;
unsigned int moves = 0;
std::set<ClassId> classes{};
auto batches = strategy_->calculateBatchSizes(cache_,assignedMemory);

Expand All @@ -74,36 +84,34 @@ void BackgroundEvictor<CacheT>::checkAndRun() {
continue;
}

stats.evictionSize.add(batch * mpStats.acStats.at(cid).allocSize);
totalBytesMoved.add(batch * mpStats.acStats.at(cid).allocSize);

//try evicting BATCH items from the class in order to reach free target
auto evicted =
BackgroundEvictorAPIWrapper<CacheT>::traverseAndEvictItems(cache_,
tid,pid,cid,batch);
evictions += evicted;
evictions_per_class_[tid][pid][cid] += evicted;
//try moving BATCH items from the class in order to reach free target
auto moved = moverFunc(cache_,tid,pid,cid,batch);
moves += moved;
moves_per_class_[tid][pid][cid] += moved;
}

stats.numTraversals.inc();
stats.numEvictedItems.add(evictions);
stats.totalClasses.add(classes.size());
numTraversals.inc();
numMovedItems.add(moves);
totalClasses.add(classes.size());
}

template <typename CacheT>
BackgroundEvictionStats BackgroundEvictor<CacheT>::getStats() const noexcept {
BackgroundEvictionStats evicStats;
evicStats.numEvictedItems = stats.numEvictedItems.get();
evicStats.runCount = stats.numTraversals.get();
evicStats.evictionSize = stats.evictionSize.get();
evicStats.totalClasses = stats.totalClasses.get();

return evicStats;
BackgroundMoverStats BackgroundMover<CacheT>::getStats() const noexcept {
BackgroundMoverStats stats;
stats.numMovedItems = numMovedItems.get();
stats.runCount = numTraversals.get();
stats.totalBytesMoved = totalBytesMoved.get();
stats.totalClasses = totalClasses.get();

return stats;
}

template <typename CacheT>
std::map<TierId, std::map<PoolId, std::map<ClassId, uint64_t>>>
BackgroundEvictor<CacheT>::getClassStats() const noexcept {
return evictions_per_class_;
BackgroundMover<CacheT>::getClassStats() const noexcept {
return moves_per_class_;
}

} // namespace cachelib
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,79 +21,81 @@

#include "cachelib/allocator/CacheStats.h"
#include "cachelib/common/PeriodicWorker.h"
#include "cachelib/allocator/BackgroundEvictorStrategy.h"
#include "cachelib/allocator/BackgroundMoverStrategy.h"
#include "cachelib/common/AtomicCounter.h"


namespace facebook {
namespace cachelib {

// wrapper that exposes the private APIs of CacheType that are specifically
// needed for the eviction.
// needed for the cache api
template <typename C>
struct BackgroundEvictorAPIWrapper {
struct BackgroundMoverAPIWrapper {

static size_t traverseAndEvictItems(C& cache,
unsigned int tid, unsigned int pid, unsigned int cid, size_t batch) {
return cache.traverseAndEvictItems(tid,pid,cid,batch);
}

static size_t traverseAndPromoteItems(C& cache,
unsigned int tid, unsigned int pid, unsigned int cid, size_t batch) {
return cache.traverseAndPromoteItems(tid,pid,cid,batch);
}

};

struct BackgroundEvictorStats {
// items evicted
AtomicCounter numEvictedItems{0};

// traversals
AtomicCounter numTraversals{0};

// total class size
AtomicCounter totalClasses{0};

// item eviction size
AtomicCounter evictionSize{0};
enum class MoverDir {
Evict = 0,
Promote
};

// Periodic worker that evicts items from tiers in batches
// The primary aim is to reduce insertion times for new items in the
// cache
template <typename CacheT>
class BackgroundEvictor : public PeriodicWorker {
class BackgroundMover : public PeriodicWorker {
public:
using Cache = CacheT;
// @param cache the cache interface
// @param target_free the target amount of memory to keep free in
// this tier
// @param tier id memory tier to perform eviction on
BackgroundEvictor(Cache& cache,
std::shared_ptr<BackgroundEvictorStrategy> strategy);
// @param strategy the stragey class that defines how objects are moved,
// (promoted vs. evicted and how much)
BackgroundMover(Cache& cache,
std::shared_ptr<BackgroundMoverStrategy> strategy,
MoverDir direction_);

~BackgroundEvictor() override;
~BackgroundMover() override;

BackgroundEvictionStats getStats() const noexcept;
BackgroundMoverStats getStats() const noexcept;
std::map<TierId, std::map<PoolId, std::map<ClassId, uint64_t>>> getClassStats() const noexcept;

void setAssignedMemory(std::vector<std::tuple<TierId, PoolId, ClassId>> &&assignedMemory);

private:
std::map<TierId, std::map<PoolId, std::map<ClassId, uint64_t>>> evictions_per_class_;

std::map<TierId, std::map<PoolId, std::map<ClassId, uint64_t>>> moves_per_class_;
// cache allocator's interface for evicting

using Item = typename Cache::Item;

Cache& cache_;
std::shared_ptr<BackgroundEvictorStrategy> strategy_;
std::shared_ptr<BackgroundMoverStrategy> strategy_;
MoverDir direction_;

std::function<size_t(Cache&, unsigned int, unsigned int, unsigned int, size_t)> moverFunc;

// implements the actual logic of running the background evictor
void work() override final;
void checkAndRun();

BackgroundEvictorStats stats;

AtomicCounter numMovedItems{0};
AtomicCounter numTraversals{0};
AtomicCounter totalClasses{0};
AtomicCounter totalBytesMoved{0};

std::vector<std::tuple<TierId, PoolId, ClassId>> assignedMemory_;
folly::DistributedMutex mutex;
};
} // namespace cachelib
} // namespace facebook

#include "cachelib/allocator/BackgroundEvictor-inl.h"
#include "cachelib/allocator/BackgroundMover-inl.h"
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace facebook {
namespace cachelib {

// Base class for background eviction strategy.
class BackgroundEvictorStrategy {
class BackgroundMoverStrategy {

public:
virtual std::vector<size_t> calculateBatchSizes(const CacheBase& cache,
Expand Down
109 changes: 0 additions & 109 deletions cachelib/allocator/BackgroundPromoter-inl.h

This file was deleted.

Loading