ClickHouse/utils/keeper-bench/Stats.cpp

178 lines
5.0 KiB
C++
Raw Normal View History

2021-04-12 08:10:23 +00:00
#include "Stats.h"
#include <iostream>
2023-04-14 13:32:08 +00:00
#include <rapidjson/document.h>
#include <rapidjson/rapidjson.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
void Stats::StatsCollector::add(uint64_t microseconds, size_t requests_inc, size_t bytes_inc)
{
work_time += microseconds;
requests += requests_inc;
requests_bytes += bytes_inc;
sampler.insert(microseconds);
}
void Stats::addRead(uint64_t microseconds, size_t requests_inc, size_t bytes_inc)
{
read_collector.add(microseconds, requests_inc, bytes_inc);
}
void Stats::addWrite(uint64_t microseconds, size_t requests_inc, size_t bytes_inc)
{
write_collector.add(microseconds, requests_inc, bytes_inc);
}
void Stats::StatsCollector::clear()
{
requests = 0;
work_time = 0;
requests_bytes = 0;
sampler.clear();
}
void Stats::clear()
{
read_collector.clear();
write_collector.clear();
}
std::pair<double, double> Stats::StatsCollector::getThroughput(size_t concurrency)
{
assert(requests != 0);
double seconds = work_time / 1'000'000.0 / concurrency;
return {requests / seconds, requests_bytes / seconds};
}
double Stats::StatsCollector::getPercentile(double percent)
{
return sampler.quantileNearest(percent / 100.0) / 1000.0;
}
void Stats::report(size_t concurrency)
2021-04-12 08:10:23 +00:00
{
std::cerr << "\n";
2023-04-14 13:32:08 +00:00
const auto & read_requests = read_collector.requests;
const auto & write_requests = write_collector.requests;
2021-04-12 15:40:42 +00:00
/// Avoid zeros, nans or exceptions
2023-04-14 13:32:08 +00:00
if (0 == read_requests && 0 == write_requests)
2021-04-12 15:40:42 +00:00
return;
2021-04-12 08:10:23 +00:00
2023-04-14 13:32:08 +00:00
auto [read_rps, read_bps] = read_collector.getThroughput(concurrency);
auto [write_rps, write_bps] = write_collector.getThroughput(concurrency);
2021-04-12 08:10:23 +00:00
2023-04-14 13:32:08 +00:00
std::cerr << "read requests " << read_requests << ", write requests " << write_requests << ", ";
if (errors)
std::cerr << "errors " << errors << ", ";
if (0 != read_requests)
2021-04-13 11:55:08 +00:00
{
std::cerr
2023-04-14 13:32:08 +00:00
<< "Read RPS: " << read_rps << ", "
<< "Read MiB/s: " << read_bps / 1048576;
if (0 != write_requests)
2021-04-13 11:55:08 +00:00
std::cerr << ", ";
}
2023-04-14 13:32:08 +00:00
if (0 != write_requests)
2021-04-13 11:55:08 +00:00
{
std::cerr
2023-04-14 13:32:08 +00:00
<< "Write RPS: " << write_rps << ", "
<< "Write MiB/s: " << write_bps / 1048576 << ". "
2021-04-12 15:40:42 +00:00
<< "\n";
2021-04-13 11:55:08 +00:00
}
2021-04-12 08:10:23 +00:00
std::cerr << "\n";
2023-04-14 13:32:08 +00:00
auto print_percentile = [&](double percent, Stats::StatsCollector & collector)
2021-04-12 08:10:23 +00:00
{
std::cerr << percent << "%\t\t";
2023-04-14 13:32:08 +00:00
std::cerr << collector.getPercentile(percent) << " msec.\t";
2021-04-12 08:10:23 +00:00
std::cerr << "\n";
};
2023-04-14 13:32:08 +00:00
const auto print_all_percentiles = [&](auto & collector)
2021-04-13 11:55:08 +00:00
{
for (int percent = 0; percent <= 90; percent += 10)
2023-04-14 13:32:08 +00:00
print_percentile(percent, collector);
2021-04-13 11:55:08 +00:00
2023-04-14 13:32:08 +00:00
print_percentile(95, collector);
print_percentile(99, collector);
print_percentile(99.9, collector);
print_percentile(99.99, collector);
};
if (0 != read_requests)
{
std::cerr << "Read sampler:\n";
print_all_percentiles(read_collector);
2021-04-13 11:55:08 +00:00
}
2021-04-12 08:10:23 +00:00
2023-04-14 13:32:08 +00:00
if (0 != write_requests)
2021-04-13 11:55:08 +00:00
{
std::cerr << "Write sampler:\n";
2023-04-14 13:32:08 +00:00
print_all_percentiles(write_collector);
}
}
2023-04-17 11:25:46 +00:00
void Stats::writeJSON(DB::WriteBuffer & out, size_t concurrency, int64_t start_timestamp)
2023-04-14 13:32:08 +00:00
{
using namespace rapidjson;
Document results;
auto & allocator = results.GetAllocator();
results.SetObject();
2023-04-17 11:25:46 +00:00
results.AddMember("timestamp", Value(start_timestamp), allocator);
2023-04-14 13:32:08 +00:00
const auto get_results = [&](auto & collector)
{
Value specific_results(kObjectType);
specific_results.AddMember("total_requests", Value(static_cast<uint64_t>(collector.requests)), allocator);
2023-04-17 11:25:46 +00:00
2023-04-14 13:32:08 +00:00
auto [rps, bps] = collector.getThroughput(concurrency);
specific_results.AddMember("requests_per_second", Value(rps), allocator);
specific_results.AddMember("bytes_per_second", Value(bps), allocator);
Value percentiles(kArrayType);
const auto add_percentile = [&](double percent)
{
Value percentile(kObjectType);
2023-04-17 11:25:46 +00:00
Value percent_key(fmt::format("{:.2f}", percent).c_str(), allocator);
percentile.AddMember(percent_key, Value(collector.getPercentile(percent)), allocator);
2023-04-14 13:32:08 +00:00
percentiles.PushBack(percentile, allocator);
};
2021-04-13 11:55:08 +00:00
for (int percent = 0; percent <= 90; percent += 10)
2023-04-14 13:32:08 +00:00
add_percentile(percent);
2021-04-13 11:55:08 +00:00
2023-04-14 13:32:08 +00:00
add_percentile(95);
add_percentile(99);
add_percentile(99.9);
add_percentile(99.99);
specific_results.AddMember("percentiles", percentiles, allocator);
return specific_results;
};
if (read_collector.requests != 0)
results.AddMember("read_results", get_results(read_collector), results.GetAllocator());
if (write_collector.requests != 0)
results.AddMember("write_results", get_results(write_collector), results.GetAllocator());
StringBuffer strbuf;
strbuf.Clear();
Writer<StringBuffer> writer(strbuf);
results.Accept(writer);
const char * output_string = strbuf.GetString();
out.write(output_string, strlen(output_string));
2021-04-12 08:10:23 +00:00
}