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:
parent
5e843d0494
commit
e542ef76fb
4 changed files with 168 additions and 37 deletions
|
@ -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};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
153
ircd/db.cc
153
ircd/db.cc
|
@ -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);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue