in src/kudu/tools/rebalancer.cc [101:208]
Status Rebalancer::PrintStats(std::ostream& out) {
// First, report on the current balance state of the cluster.
RETURN_NOT_OK(ResetKsck());
ignore_result(ksck_->Run());
const KsckResults& results = ksck_->results();
ClusterBalanceInfo cbi;
RETURN_NOT_OK(KsckResultsToClusterBalanceInfo(results, MovesInProgress(), &cbi));
// Per-server replica distribution stats.
{
out << "Per-server replica distribution summary:" << endl;
DataTable summary({"Statistic", "Value"});
const auto& servers_load_info = cbi.servers_by_total_replica_count;
if (servers_load_info.empty()) {
summary.AddRow({ "N/A", "N/A" });
} else {
const int64_t total_replica_count = accumulate(
servers_load_info.begin(), servers_load_info.end(), 0L,
[](int64_t sum, const pair<int32_t, string>& elem) {
return sum + elem.first;
});
const auto min_replica_count = servers_load_info.begin()->first;
const auto max_replica_count = servers_load_info.rbegin()->first;
const double avg_replica_count =
1.0 * total_replica_count / servers_load_info.size();
summary.AddRow({ "Minimum Replica Count", to_string(min_replica_count) });
summary.AddRow({ "Maximum Replica Count", to_string(max_replica_count) });
summary.AddRow({ "Average Replica Count", to_string(avg_replica_count) });
}
RETURN_NOT_OK(summary.PrintTo(out));
out << endl;
if (config_.output_replica_distribution_details) {
const auto& tserver_summaries = results.tserver_summaries;
unordered_map<string, string> tserver_endpoints;
for (const auto& summary : tserver_summaries) {
tserver_endpoints.emplace(summary.uuid, summary.address);
}
out << "Per-server replica distribution details:" << endl;
DataTable servers_info({ "UUID", "Address", "Replica Count" });
for (const auto& elem : servers_load_info) {
const auto& id = elem.second;
servers_info.AddRow({ id, tserver_endpoints[id], to_string(elem.first) });
}
RETURN_NOT_OK(servers_info.PrintTo(out));
out << endl;
}
}
// Per-table replica distribution stats.
{
out << "Per-table replica distribution summary:" << endl;
DataTable summary({ "Replica Skew", "Value" });
const auto& table_skew_info = cbi.table_info_by_skew;
if (table_skew_info.empty()) {
summary.AddRow({ "N/A", "N/A" });
} else {
const auto min_table_skew = table_skew_info.begin()->first;
const auto max_table_skew = table_skew_info.rbegin()->first;
const int64_t sum_table_skew = accumulate(
table_skew_info.begin(), table_skew_info.end(), 0L,
[](int64_t sum, const pair<int32_t, TableBalanceInfo>& elem) {
return sum + elem.first;
});
double avg_table_skew = 1.0 * sum_table_skew / table_skew_info.size();
summary.AddRow({ "Minimum", to_string(min_table_skew) });
summary.AddRow({ "Maximum", to_string(max_table_skew) });
summary.AddRow({ "Average", to_string(avg_table_skew) });
}
RETURN_NOT_OK(summary.PrintTo(out));
out << endl;
if (config_.output_replica_distribution_details) {
const auto& table_summaries = results.table_summaries;
unordered_map<string, const KsckTableSummary*> table_info;
for (const auto& summary : table_summaries) {
table_info.emplace(summary.id, &summary);
}
out << "Per-table replica distribution details:" << endl;
DataTable skew(
{ "Table Id", "Replica Count", "Replica Skew", "Table Name" });
for (const auto& elem : table_skew_info) {
const auto& table_id = elem.second.table_id;
const auto it = table_info.find(table_id);
const auto* table_summary =
(it == table_info.end()) ? nullptr : it->second;
const auto& table_name = table_summary ? table_summary->name : "";
const auto total_replica_count = table_summary
? table_summary->replication_factor * table_summary->TotalTablets()
: 0;
skew.AddRow({ table_id,
to_string(total_replica_count),
to_string(elem.first),
table_name });
}
RETURN_NOT_OK(skew.PrintTo(out));
out << endl;
}
}
return Status::OK();
}