0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::db: Add per-cache statistics.

This commit is contained in:
Jason Volk 2018-09-26 18:00:18 -07:00
parent 5e843d0494
commit e542ef76fb
4 changed files with 168 additions and 37 deletions

View file

@ -21,11 +21,9 @@
namespace ircd::db
{
struct cache_stats;
// Get our stats
const cache_stats &stats(const rocksdb::Cache &);
cache_stats stats(const rocksdb::Cache *const &);
// Get our stats; refer to db/stats.h for ticker ID related.
const uint64_t &ticker(const rocksdb::Cache &, const uint32_t &ticker_id);
uint64_t ticker(const rocksdb::Cache *const &, const uint32_t &ticker_id);
// Get capacity
size_t capacity(const rocksdb::Cache &);
@ -68,13 +66,3 @@ namespace ircd::db
void clear(rocksdb::Cache &);
void clear(rocksdb::Cache *const &);
}
/// Our custom cache statistics. Though the rocksdb::Statistics ticker could
/// be instantiated for each cache we have our own counters, and we let the
/// rocksdb cache impl update our database ticker instead for aggregate stats.
struct ircd::db::cache_stats
{
size_t inserts {0};
size_t misses {0};
size_t hits {0};
};

View file

@ -34,8 +34,8 @@ final
static const bool DEFAULT_STRICT;
database *d;
cache_stats stats;
std::shared_ptr<rocksdb::Cache> c;
struct database::stats stats;
const char *Name() const noexcept override;
Status Insert(const Slice &key, void *value, size_t charge, deleter, Handle **, Priority) noexcept override;

View file

@ -15,11 +15,13 @@
// RocksDB symbols which we cannot forward declare. It is used internally
// and does not need to be included by general users of IRCd.
struct ircd::db::database::stats final
:std::enable_shared_from_this<struct ircd::db::database::stats>
,rocksdb::Statistics
struct ircd::db::database::stats
final
:rocksdb::Statistics
{
database *d;
struct passthru;
database *d {nullptr};
std::array<uint64_t, rocksdb::TICKER_ENUM_MAX> ticker {{0}};
std::array<struct db::histogram, rocksdb::HISTOGRAM_ENUM_MAX> histogram;
@ -32,5 +34,25 @@ struct ircd::db::database::stats final
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
rocksdb::Status Reset() noexcept override;
stats(database *const &d);
stats(database *const &d = nullptr);
~stats() noexcept;
};
struct ircd::db::database::stats::passthru
final
:rocksdb::Statistics
{
std::array<rocksdb::Statistics *, 2> pass {{nullptr}};
void recordTick(const uint32_t tickerType, const uint64_t count) noexcept override;
void measureTime(const uint32_t histogramType, const uint64_t time) noexcept override;
bool HistEnabledForType(const uint32_t type) const noexcept override;
uint64_t getTickerCount(const uint32_t tickerType) const noexcept override;
void setTickerCount(const uint32_t tickerType, const uint64_t count) noexcept override;
void histogramData(const uint32_t type, rocksdb::HistogramData *) const noexcept override;
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
rocksdb::Status Reset() noexcept override;
passthru(rocksdb::Statistics *const &a, rocksdb::Statistics *const &b);
~passthru() noexcept;
};

View file

@ -1906,11 +1906,20 @@ ircd::db::histogram_max
// database::stats (db/database/stats.h) internal
//
//
// stats::stats
//
ircd::db::database::stats::stats(database *const &d)
:d{d}
{
}
ircd::db::database::stats::~stats()
noexcept
{
}
rocksdb::Status
ircd::db::database::stats::Reset()
noexcept
@ -1992,6 +2001,95 @@ const noexcept
return ticker.at(type);
}
//
// database::stats::passthru
//
ircd::db::database::stats::passthru::passthru(rocksdb::Statistics *const &a,
rocksdb::Statistics *const &b)
:pass
{
{ a, b }
}
{
}
ircd::db::database::stats::passthru::~passthru()
noexcept
{
}
[[noreturn]]
rocksdb::Status
ircd::db::database::stats::passthru::Reset()
noexcept
{
throw assertive {"Unavailable for passthru"};
}
void
ircd::db::database::stats::passthru::recordTick(const uint32_t tickerType,
const uint64_t count)
noexcept
{
for(auto *const &pass : this->pass)
pass->recordTick(tickerType, count);
}
void
ircd::db::database::stats::passthru::measureTime(const uint32_t histogramType,
const uint64_t time)
noexcept
{
for(auto *const &pass : this->pass)
pass->measureTime(histogramType, time);
}
bool
ircd::db::database::stats::passthru::HistEnabledForType(const uint32_t type)
const noexcept
{
return std::all_of(begin(pass), end(pass), [&type]
(const auto *const &pass)
{
return pass->HistEnabledForType(type);
});
}
[[noreturn]]
uint64_t
ircd::db::database::stats::passthru::getTickerCount(const uint32_t tickerType)
const noexcept
{
throw assertive {"Unavailable for passthru"};
}
[[noreturn]]
void
ircd::db::database::stats::passthru::setTickerCount(const uint32_t tickerType,
const uint64_t count)
noexcept
{
throw assertive {"Unavailable for passthru"};
}
[[noreturn]]
void
ircd::db::database::stats::passthru::histogramData(const uint32_t type,
rocksdb::HistogramData *const data)
const noexcept
{
throw assertive {"Unavailable for passthru"};
}
[[noreturn]]
uint64_t
ircd::db::database::stats::passthru::getAndResetTickerCount(const uint32_t tickerType)
noexcept
{
throw assertive {"Unavailable for passthru"};
}
///////////////////////////////////////////////////////////////////////////////
//
// database::events
@ -2246,13 +2344,15 @@ ircd::db::database::cache::cache(database *const &d,
{
rocksdb::NewLRUCache
(
std::max(initial_capacity, ssize_t(0)),
DEFAULT_SHARD_BITS,
DEFAULT_STRICT,
DEFAULT_HI_PRIO
std::max(initial_capacity, ssize_t(0))
,DEFAULT_SHARD_BITS
,DEFAULT_STRICT
,DEFAULT_HI_PRIO
)
}
,stats{d}
{
assert(bool(c));
}
ircd::db::database::cache::~cache()
@ -2283,7 +2383,9 @@ noexcept
c->Insert(key, value, charge, del, handle, priority)
};
stats.inserts += ret.ok();
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_ADD, ret.ok());
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_ADD_FAILURES, !ret.ok());
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_DATA_BYTES_INSERT, ret.ok()? charge : 0UL);
return ret;
}
@ -2293,13 +2395,30 @@ ircd::db::database::cache::Lookup(const Slice &key,
noexcept
{
assert(bool(c));
auto *const &ret
database::stats::passthru passthru
{
c->Lookup(key, statistics)
&this->stats, statistics
};
stats.hits += bool(ret);
stats.misses += !bool(ret);
rocksdb::Statistics *const s
{
statistics?
dynamic_cast<rocksdb::Statistics *>(&passthru):
dynamic_cast<rocksdb::Statistics *>(&this->stats)
};
auto *const &ret
{
c->Lookup(key, s)
};
// Rocksdb's LRUCache stats are broke. The statistics ptr is null and
// passing it to Lookup() does nothing internally. We have to do this
// here ourselves :/
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_HIT, bool(ret));
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_MISS, !bool(ret));
return ret;
}
@ -8885,21 +9004,23 @@ ircd::db::capacity(const rocksdb::Cache &cache)
return cache.GetCapacity();
}
ircd::db::cache_stats
ircd::db::stats(const rocksdb::Cache *const &cache)
uint64_t
ircd::db::ticker(const rocksdb::Cache *const &cache,
const uint32_t &ticker_id)
{
return cache? stats(*cache) : cache_stats{};
return cache? ticker(*cache, ticker_id) : 0UL;
}
const ircd::db::cache_stats &
ircd::db::stats(const rocksdb::Cache &cache)
const uint64_t &
ircd::db::ticker(const rocksdb::Cache &cache,
const uint32_t &ticker_id)
{
const auto &dc
const auto &c
{
dynamic_cast<const database::cache &>(cache)
};
return dc.stats;
return c.stats.ticker.at(ticker_id);
}
///////////////////////////////////////////////////////////////////////////////