1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-14 12:12:21 +00:00

Add write time stats to celldb/db_stats.txt (#972)

Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
EmelyanenkoK 2024-04-25 18:45:39 +03:00 committed by GitHub
parent 25f61dff16
commit d2b012c883
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 148 additions and 57 deletions

View file

@ -87,4 +87,8 @@ void PerfWarningTimer::reset() {
start_at_ = 0;
}
double PerfWarningTimer::elapsed() const {
return Time::now() - start_at_;
}
} // namespace td

View file

@ -53,6 +53,7 @@ class PerfWarningTimer {
PerfWarningTimer &operator=(PerfWarningTimer &&) = delete;
~PerfWarningTimer();
void reset();
double elapsed() const;
private:
string name_;

View file

@ -25,6 +25,8 @@ set(VALIDATOR_DB_SOURCE
db/statedb.cpp
db/staticfilesdb.cpp
db/staticfilesdb.hpp
db/db-utils.cpp
db/db-utils.h
db/package.hpp
db/package.cpp

View file

@ -24,6 +24,7 @@
#include "td/utils/port/path.h"
#include "common/delay.h"
#include "files-async.hpp"
#include "db-utils.h"
namespace ton {
@ -41,16 +42,14 @@ class PackageStatistics {
void record_read(double time, uint64_t bytes) {
read_bytes.fetch_add(bytes, std::memory_order_relaxed);
std::lock_guard<std::mutex> guard(read_mutex);
std::lock_guard guard(read_mutex);
read_time.insert(time);
read_time_sum += time;
}
void record_write(double time, uint64_t bytes) {
write_bytes.fetch_add(bytes, std::memory_order_relaxed);
std::lock_guard<std::mutex> guard(write_mutex);
std::lock_guard guard(write_mutex);
write_time.insert(time);
write_time_sum += time;
}
std::string to_string_and_reset() {
@ -64,68 +63,35 @@ class PackageStatistics {
ss << "ton.pack.read.bytes COUNT : " << read_bytes.exchange(0, std::memory_order_relaxed) << "\n";
ss << "ton.pack.write.bytes COUNT : " << write_bytes.exchange(0, std::memory_order_relaxed) << "\n";
std::multiset<double> temp_read_time;
double temp_read_time_sum;
PercentileStats temp_read_time;
{
std::lock_guard<std::mutex> guard(read_mutex);
std::lock_guard guard(read_mutex);
temp_read_time = std::move(read_time);
read_time.clear();
temp_read_time_sum = read_time_sum;
read_time_sum = 0;
}
auto read_stats = calculate_statistics(temp_read_time);
ss << "ton.pack.read.micros P50 : " << read_stats[0] <<
" P95 : " << read_stats[1] <<
" P99 : " << read_stats[2] <<
" P100 : " << read_stats[3] <<
" COUNT : " << temp_read_time.size() <<
" SUM : " << temp_read_time_sum << "\n";
ss << "ton.pack.read.micros " << temp_read_time.to_string() << "\n";
std::multiset<double> temp_write_time;
double temp_write_time_sum;
PercentileStats temp_write_time;
{
std::lock_guard<std::mutex> guard(write_mutex);
std::lock_guard guard(write_mutex);
temp_write_time = std::move(write_time);
write_time.clear();
temp_write_time_sum = write_time_sum;
write_time_sum = 0;
}
auto write_stats = calculate_statistics(temp_write_time);
ss << "ton.pack.write.micros P50 : " << write_stats[0] <<
" P95 : " << write_stats[1] <<
" P99 : " << write_stats[2] <<
" P100 : " << write_stats[3] <<
" COUNT : " << temp_write_time.size() <<
" SUM : " << temp_write_time_sum << "\n";
ss << "ton.pack.write.micros " << temp_write_time.to_string() << "\n";
return ss.str();
}
private:
std::atomic_uint64_t open_count;
std::atomic_uint64_t close_count;
std::multiset<double> read_time;
std::atomic_uint64_t read_bytes;
std::multiset<double> write_time;
std::atomic_uint64_t write_bytes;
double read_time_sum;
double write_time_sum;
std::atomic_uint64_t open_count{0};
std::atomic_uint64_t close_count{0};
PercentileStats read_time;
std::atomic_uint64_t read_bytes{0};
PercentileStats write_time;
std::atomic_uint64_t write_bytes{0};
mutable std::mutex read_mutex;
mutable std::mutex write_mutex;
std::vector<double> calculate_statistics(const std::multiset<double>& data) const {
if (data.empty()) return {0, 0, 0, 0};
auto size = data.size();
auto calc_percentile = [&](double p) -> double {
auto it = data.begin();
std::advance(it, static_cast<int>(std::ceil(p * double(size)) - 1));
return *it;
};
return {calc_percentile(0.5), calc_percentile(0.95), calc_percentile(0.99), *data.rbegin()};
}
};
void DbStatistics::init() {

View file

@ -89,7 +89,7 @@ void CellDbIn::start_up() {
statistics_flush_at_ = td::Timestamp::in(60.0);
}
cell_db_ = std::make_shared<td::RocksDb>(td::RocksDb::open(path_, statistics_).move_as_ok());
boc_ = vm::DynamicBagOfCellsDb::create();
boc_->set_celldb_compress_depth(opts_->get_celldb_compress_depth());
@ -155,6 +155,9 @@ void CellDbIn::store_cell(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promi
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
promise.set_result(boc_->load_cell(cell->get_hash().as_slice()));
if (!opts_->get_disable_rocksdb_stats()) {
cell_db_statistics_.store_cell_time_.insert(timer.elapsed() * 1e6);
}
}
void CellDbIn::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) {
@ -162,8 +165,9 @@ void CellDbIn::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>>
}
void CellDbIn::flush_db_stats() {
auto stats = td::RocksDb::statistics_to_string(statistics_);
auto to_file_r = td::FileFd::open(path_ + "/db_stats.txt", td::FileFd::Truncate | td::FileFd::Create | td::FileFd::Write, 0644);
auto stats = td::RocksDb::statistics_to_string(statistics_) + cell_db_statistics_.to_string();
auto to_file_r =
td::FileFd::open(path_ + "/db_stats.txt", td::FileFd::Truncate | td::FileFd::Create | td::FileFd::Write, 0644);
if (to_file_r.is_error()) {
LOG(ERROR) << "Failed to open db_stats.txt: " << to_file_r.move_as_error();
return;
@ -176,6 +180,7 @@ void CellDbIn::flush_db_stats() {
return;
}
td::RocksDb::reset_statistics(statistics_);
cell_db_statistics_.clear();
}
void CellDbIn::alarm() {
@ -278,6 +283,9 @@ void CellDbIn::gc_cont2(BlockHandle handle) {
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
DCHECK(get_block(key_hash).is_error());
if (!opts_->get_disable_rocksdb_stats()) {
cell_db_statistics_.gc_cell_time_.insert(timer.elapsed() * 1e6);
}
}
void CellDbIn::skip_gc() {
@ -441,6 +449,14 @@ td::BufferSlice CellDbIn::DbEntry::release() {
return create_serialize_tl_object<ton_api::db_celldb_value>(create_tl_block_id(block_id), prev, next, root_hash);
}
std::string CellDbIn::CellDbStatistics::to_string() {
td::StringBuilder ss;
ss << "ton.celldb.store_cell.micros " << store_cell_time_.to_string() << "\n";
ss << "ton.celldb.gc_cell.micros " << gc_cell_time_.to_string() << "\n";
ss << "ton.celldb.total_time.micros : " << (td::Timestamp::now().at() - stats_start_time_.at()) * 1e6 << "\n";
return ss.as_cslice().str();
}
} // namespace validator
} // namespace ton

View file

@ -26,6 +26,7 @@
#include "interfaces/block-handle.h"
#include "auto/tl/ton_api.h"
#include "validator.h"
#include "db-utils.h"
namespace rocksdb {
class Statistics;
@ -42,9 +43,11 @@ class CellDbAsyncExecutor;
class CellDbBase : public td::actor::Actor {
public:
virtual void start_up();
void start_up() override;
protected:
std::shared_ptr<vm::DynamicBagOfCellsDb::AsyncExecutor> async_executor;
private:
void execute_sync(std::function<void()> f);
friend CellDbAsyncExecutor;
@ -76,8 +79,7 @@ class CellDbIn : public CellDbBase {
RootHash root_hash;
DbEntry(tl_object_ptr<ton_api::db_celldb_value> entry);
DbEntry() {
}
DbEntry() = default;
DbEntry(BlockIdExt block_id, KeyHash prev, KeyHash next, RootHash root_hash)
: block_id(block_id), prev(prev), next(next), root_hash(root_hash) {
}
@ -109,8 +111,6 @@ class CellDbIn : public CellDbBase {
std::unique_ptr<vm::DynamicBagOfCellsDb> boc_;
std::shared_ptr<vm::KeyValue> cell_db_;
std::shared_ptr<rocksdb::Statistics> statistics_;
td::Timestamp statistics_flush_at_ = td::Timestamp::never();
std::function<void(const vm::CellLoader::LoadResult&)> on_load_callback_;
std::set<td::Bits256> cells_to_migrate_;
@ -127,6 +127,21 @@ class CellDbIn : public CellDbBase {
};
std::unique_ptr<MigrationStats> migration_stats_;
struct CellDbStatistics {
PercentileStats store_cell_time_;
PercentileStats gc_cell_time_;
td::Timestamp stats_start_time_ = td::Timestamp::now();
std::string to_string();
void clear() {
*this = CellDbStatistics{};
}
};
std::shared_ptr<rocksdb::Statistics> statistics_;
CellDbStatistics cell_db_statistics_;
td::Timestamp statistics_flush_at_ = td::Timestamp::never();
public:
class MigrationProxy : public td::actor::Actor {
public:

54
validator/db/db-utils.cpp Normal file
View file

@ -0,0 +1,54 @@
/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "db-utils.h"
#include "td/utils/logging.h"
#include <cmath>
namespace ton::validator {
void PercentileStats::insert(double value) {
values_.insert(value);
}
std::string PercentileStats::to_string() const {
double percentiles[4] = {0.0, 0.0, 0.0, 0.0};
double sum = 0.0;
size_t size = values_.size();
if (!values_.empty()) {
size_t indices[4] = {(size_t)std::ceil(0.5 * (double)size) - 1, (size_t)std::ceil(0.95 * (double)size) - 1,
(size_t)std::ceil(0.99 * (double)size) - 1, size - 1};
size_t i = 0;
for (auto it = values_.begin(); it != values_.end(); ++it, ++i) {
for (size_t j = 0; j < 4; ++j) {
if (indices[j] == i) {
percentiles[j] = *it;
}
}
sum += *it;
}
}
return PSTRING() << "P50 : " << percentiles[0] << " P95 : " << percentiles[1] << " P99 : " << percentiles[2]
<< " P100 : " << percentiles[3] << " COUNT : " << size << " SUM : " << sum;
}
void PercentileStats::clear() {
values_.clear();
}
} // namespace ton::validator

33
validator/db/db-utils.h Normal file
View file

@ -0,0 +1,33 @@
/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <set>
#include <string>
namespace ton::validator {
class PercentileStats {
public:
void insert(double value);
std::string to_string() const;
void clear();
private:
std::multiset<double> values_;
};
} // namespace ton::validator