mirror of https://gitee.com/bigwinds/arangodb
Improved RocksDB engine statistics with docs and rest endpoint (#2598)
* Improved statistics reporting for RocksDB engine (including cache info). * Added documentation about db._engineStats(). * Added rest endpoint for engine stats.
This commit is contained in:
parent
9b53d3cd45
commit
a0c4e3d9df
|
@ -184,3 +184,12 @@ database. The *_system* database itself cannot be dropped.
|
||||||
Databases are dropped asynchronously, and will be physically removed if
|
Databases are dropped asynchronously, and will be physically removed if
|
||||||
all clients have disconnected and references have been garbage-collected.
|
all clients have disconnected and references have been garbage-collected.
|
||||||
|
|
||||||
|
### Engine statistics
|
||||||
|
|
||||||
|
retrieve statistics related to the storage engine-rocksdb
|
||||||
|
`db._engineStats()`
|
||||||
|
|
||||||
|
Returns some statistics related to storage engine activity, including figures
|
||||||
|
about data size, cache usage, etc.
|
||||||
|
|
||||||
|
**Note**: Currently this only produces useful output for the RocksDB engine.
|
||||||
|
|
|
@ -257,8 +257,8 @@ std::pair<double, double> Manager::globalHitRates() {
|
||||||
uint64_t currentHits = _findHits.load();
|
uint64_t currentHits = _findHits.load();
|
||||||
uint64_t currentMisses = _findMisses.load();
|
uint64_t currentMisses = _findMisses.load();
|
||||||
if (currentHits + currentMisses > 0) {
|
if (currentHits + currentMisses > 0) {
|
||||||
lifetimeRate = 100 * (static_cast<double>(currentHits) /
|
lifetimeRate = 100.0 * (static_cast<double>(currentHits) /
|
||||||
static_cast<double>(currentHits + currentMisses));
|
static_cast<double>(currentHits + currentMisses));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_enableWindowedStats && _findStats.get() != nullptr) {
|
if (_enableWindowedStats && _findStats.get() != nullptr) {
|
||||||
|
@ -278,8 +278,9 @@ std::pair<double, double> Manager::globalHitRates() {
|
||||||
currentMisses = (*stats)[0].second;
|
currentMisses = (*stats)[0].second;
|
||||||
}
|
}
|
||||||
if (currentHits + currentMisses > 0) {
|
if (currentHits + currentMisses > 0) {
|
||||||
windowedRate = 100 * (static_cast<double>(currentHits) /
|
windowedRate =
|
||||||
static_cast<double>(currentHits + currentMisses));
|
100.0 * (static_cast<double>(currentHits) /
|
||||||
|
static_cast<double>(currentHits + currentMisses));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -750,8 +751,8 @@ std::shared_ptr<Manager::PriorityList> Manager::priorityList() {
|
||||||
double baseWeight = std::max(minimumWeight, uniformMarginalWeight);
|
double baseWeight = std::max(minimumWeight, uniformMarginalWeight);
|
||||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||||
if (1.0 < (baseWeight * static_cast<double>(_caches.size()))) {
|
if (1.0 < (baseWeight * static_cast<double>(_caches.size()))) {
|
||||||
LOG_TOPIC(FATAL, Logger::FIXME) << "weight: " << baseWeight
|
LOG_TOPIC(FATAL, Logger::FIXME)
|
||||||
<< ", count: " << _caches.size();
|
<< "weight: " << baseWeight << ", count: " << _caches.size();
|
||||||
TRI_ASSERT(1.0 >= (baseWeight * static_cast<double>(_caches.size())));
|
TRI_ASSERT(1.0 >= (baseWeight * static_cast<double>(_caches.size())));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -443,11 +443,11 @@ void GeneralServerFeature::defineHandlers() {
|
||||||
AsyncJobManager*>,
|
AsyncJobManager*>,
|
||||||
_jobManager.get());
|
_jobManager.get());
|
||||||
|
|
||||||
_handlerFactory->addHandler(
|
_handlerFactory->addPrefixHandler(
|
||||||
"/_api/version", RestHandlerCreator<RestVersionHandler>::createNoData);
|
"/_api/engine", RestHandlerCreator<RestEngineHandler>::createNoData);
|
||||||
|
|
||||||
_handlerFactory->addHandler(
|
_handlerFactory->addHandler(
|
||||||
"/_api/engine", RestHandlerCreator<RestEngineHandler>::createNoData);
|
"/_api/version", RestHandlerCreator<RestVersionHandler>::createNoData);
|
||||||
|
|
||||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||||
_handlerFactory->addHandler(
|
_handlerFactory->addHandler(
|
||||||
|
|
|
@ -38,10 +38,51 @@ RestEngineHandler::RestEngineHandler(GeneralRequest* request,
|
||||||
: RestBaseHandler(request, response) {}
|
: RestBaseHandler(request, response) {}
|
||||||
|
|
||||||
RestStatus RestEngineHandler::execute() {
|
RestStatus RestEngineHandler::execute() {
|
||||||
|
// extract the sub-request type
|
||||||
|
auto const type = _request->requestType();
|
||||||
|
|
||||||
|
if (type == rest::RequestType::GET) {
|
||||||
|
handleGet();
|
||||||
|
return RestStatus::DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
generateError(rest::ResponseCode::METHOD_NOT_ALLOWED,
|
||||||
|
TRI_ERROR_HTTP_METHOD_NOT_ALLOWED);
|
||||||
|
return RestStatus::DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestEngineHandler::handleGet() {
|
||||||
|
std::vector<std::string> const& suffixes = _request->suffixes();
|
||||||
|
|
||||||
|
if (suffixes.size() > 1 || (suffixes.size() == 1 && suffixes[0] != "stats")) {
|
||||||
|
generateError(rest::ResponseCode::BAD, TRI_ERROR_BAD_PARAMETER,
|
||||||
|
"expecting GET /_api/engine[/stats]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suffixes.size() == 0) {
|
||||||
|
getCapabilities();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStats();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestEngineHandler::getCapabilities() {
|
||||||
VPackBuilder result;
|
VPackBuilder result;
|
||||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||||
engine->getCapabilities(result);
|
engine->getCapabilities(result);
|
||||||
|
|
||||||
generateResult(rest::ResponseCode::OK, result.slice());
|
generateResult(rest::ResponseCode::OK, result.slice());
|
||||||
return RestStatus::DONE;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestEngineHandler::getStats() {
|
||||||
|
VPackBuilder result;
|
||||||
|
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||||
|
engine->getStatistics(result);
|
||||||
|
|
||||||
|
generateResult(rest::ResponseCode::OK, result.slice());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,11 @@ class RestEngineHandler : public arangodb::RestBaseHandler {
|
||||||
char const* name() const override final { return "RestEngineHandler"; }
|
char const* name() const override final { return "RestEngineHandler"; }
|
||||||
bool isDirect() const override { return true; }
|
bool isDirect() const override { return true; }
|
||||||
RestStatus execute() override;
|
RestStatus execute() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void handleGet();
|
||||||
|
void getCapabilities();
|
||||||
|
void getStats();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "Basics/VelocyPackHelper.h"
|
#include "Basics/VelocyPackHelper.h"
|
||||||
#include "Basics/WriteLocker.h"
|
#include "Basics/WriteLocker.h"
|
||||||
#include "Basics/build.h"
|
#include "Basics/build.h"
|
||||||
|
#include "Cache/CacheManagerFeature.h"
|
||||||
|
#include "Cache/Manager.h"
|
||||||
#include "GeneralServer/RestHandlerFactory.h"
|
#include "GeneralServer/RestHandlerFactory.h"
|
||||||
#include "Logger/Logger.h"
|
#include "Logger/Logger.h"
|
||||||
#include "ProgramOptions/ProgramOptions.h"
|
#include "ProgramOptions/ProgramOptions.h"
|
||||||
|
@ -1414,29 +1416,52 @@ RocksDBReplicationManager* RocksDBEngine::replicationManager() const {
|
||||||
void RocksDBEngine::getStatistics(VPackBuilder& builder) const {
|
void RocksDBEngine::getStatistics(VPackBuilder& builder) const {
|
||||||
builder.openObject();
|
builder.openObject();
|
||||||
// add int properties
|
// add int properties
|
||||||
auto c1 = [&](std::string const& s) {
|
auto addInt = [&](std::string const& s) {
|
||||||
|
std::string v;
|
||||||
|
if (_db->GetProperty(s, &v)) {
|
||||||
|
int64_t i = basics::StringUtils::int64(v);
|
||||||
|
builder.add(s, VPackValue(i));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto addStr = [&](std::string const& s) {
|
||||||
std::string v;
|
std::string v;
|
||||||
if (_db->GetProperty(s, &v)) {
|
if (_db->GetProperty(s, &v)) {
|
||||||
builder.add(s, VPackValue(v));
|
builder.add(s, VPackValue(v));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
c1(rocksdb::DB::Properties::kNumImmutableMemTable);
|
auto addCf = [&](std::string const& name, rocksdb::ColumnFamilyHandle* c) {
|
||||||
c1(rocksdb::DB::Properties::kMemTableFlushPending);
|
std::string v;
|
||||||
c1(rocksdb::DB::Properties::kCompactionPending);
|
if (_db->GetProperty(c, rocksdb::DB::Properties::kCFStats, &v)) {
|
||||||
c1(rocksdb::DB::Properties::kBackgroundErrors);
|
builder.add(name, VPackValue(v));
|
||||||
c1(rocksdb::DB::Properties::kCurSizeActiveMemTable);
|
}
|
||||||
c1(rocksdb::DB::Properties::kCurSizeAllMemTables);
|
};
|
||||||
c1(rocksdb::DB::Properties::kSizeAllMemTables);
|
addInt(rocksdb::DB::Properties::kNumImmutableMemTable);
|
||||||
c1(rocksdb::DB::Properties::kNumEntriesImmMemTables);
|
addInt(rocksdb::DB::Properties::kMemTableFlushPending);
|
||||||
c1(rocksdb::DB::Properties::kNumSnapshots);
|
addInt(rocksdb::DB::Properties::kCompactionPending);
|
||||||
c1(rocksdb::DB::Properties::kDBStats);
|
addInt(rocksdb::DB::Properties::kBackgroundErrors);
|
||||||
c1(rocksdb::DB::Properties::kCFStats);
|
addInt(rocksdb::DB::Properties::kCurSizeActiveMemTable);
|
||||||
c1(rocksdb::DB::Properties::kSSTables);
|
addInt(rocksdb::DB::Properties::kCurSizeAllMemTables);
|
||||||
c1(rocksdb::DB::Properties::kNumRunningCompactions);
|
addInt(rocksdb::DB::Properties::kSizeAllMemTables);
|
||||||
c1(rocksdb::DB::Properties::kNumRunningFlushes);
|
addInt(rocksdb::DB::Properties::kNumEntriesImmMemTables);
|
||||||
c1(rocksdb::DB::Properties::kIsFileDeletionsEnabled);
|
addInt(rocksdb::DB::Properties::kNumSnapshots);
|
||||||
c1(rocksdb::DB::Properties::kBaseLevel);
|
addStr(rocksdb::DB::Properties::kDBStats);
|
||||||
c1(rocksdb::DB::Properties::kTotalSstFilesSize);
|
addStr(rocksdb::DB::Properties::kSSTables);
|
||||||
|
addInt(rocksdb::DB::Properties::kNumRunningCompactions);
|
||||||
|
addInt(rocksdb::DB::Properties::kNumRunningFlushes);
|
||||||
|
addInt(rocksdb::DB::Properties::kIsFileDeletionsEnabled);
|
||||||
|
addInt(rocksdb::DB::Properties::kBaseLevel);
|
||||||
|
addInt(rocksdb::DB::Properties::kTotalSstFilesSize);
|
||||||
|
builder.add("rocksdb.cfstats", VPackValue(VPackValueType::Object));
|
||||||
|
addCf("other", RocksDBColumnFamily::other());
|
||||||
|
addCf("documents", RocksDBColumnFamily::documents());
|
||||||
|
addCf("primary", RocksDBColumnFamily::primary());
|
||||||
|
addCf("edge", RocksDBColumnFamily::edge());
|
||||||
|
addCf("geo", RocksDBColumnFamily::geo());
|
||||||
|
addCf("fulltext", RocksDBColumnFamily::fulltext());
|
||||||
|
addCf("index", RocksDBColumnFamily::index());
|
||||||
|
addCf("uniqueIndex", RocksDBColumnFamily::uniqueIndex());
|
||||||
|
addCf("views", RocksDBColumnFamily::views());
|
||||||
|
builder.close();
|
||||||
|
|
||||||
if (_options.table_factory) {
|
if (_options.table_factory) {
|
||||||
void* options = _options.table_factory->GetOptions();
|
void* options = _options.table_factory->GetOptions();
|
||||||
|
@ -1445,6 +1470,13 @@ void RocksDBEngine::getStatistics(VPackBuilder& builder) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache::Manager* manager = CacheManagerFeature::MANAGER;
|
||||||
|
auto rates = manager->globalHitRates();
|
||||||
|
builder.add("cache.size", VPackValue(manager->globalLimit()));
|
||||||
|
builder.add("cache.used", VPackValue(manager->globalAllocation()));
|
||||||
|
builder.add("cache.hit-rate-lifetime", VPackValue(rates.first));
|
||||||
|
builder.add("cache.hit-rate-recent", VPackValue(rates.second));
|
||||||
|
|
||||||
builder.close();
|
builder.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue