一 引言
某地存储项目中由于每天都需要统计存储使用量及业务量,在某一日统计存储使用量时发现global中容量与各池的可用容量不一致,由此产生疑问。
二 Global & Pool统计
分析代码,发现ceph df在monitor中的处理逻辑是monito.cc handle_command:
这部分代码里主要分为两部分:一部分是对于Global输出的统计,另外一部分是对于各池的统计。
{
bool verbose = (detail == "detail");
if (f)
f->open_object_section("stats");
pgservice->dump_fs_stats(&ds, f.get(), verbose);//Global统计
if (!f)
ds << '\n';
pgservice->dump_pool_stats(osdmon()->osdmap, &ds, f.get(), verbose);//各存储池统计
if (f) {
f->close_section();
f->flush(ds);
ds << '\n';
}
}
非detail版本的Global主要依赖于osd_sum这个变量,这个变量的来源是osd_stat_t。osd_stat_t这个结构的值统计在update_osd_stat中。
三 Global统计
**monitor.cc:dump_fs_stats--->mgrstatmonitor.cc:dump_fs_stats**
void dump_fs_stats(stringstream *ss,
Formatter *f,
bool verbose) const override {
digest.dump_fs_stats(ss, f, verbose);
}
**mgrstatmonitor.cc:dump_fs_stats:**
void PGMapDigest::dump_fs_stats(stringstream *ss, Formatter *f, bool verbose) const
{
if (f) {
f->open_object_section("stats");
f->dump_int("total_bytes", osd_sum.kb * 1024ull);
f->dump_int("total_used_bytes", osd_sum.kb_used * 1024ull);
f->dump_int("total_avail_bytes", osd_sum.kb_avail * 1024ull);
if (verbose) {
f->dump_int("total_objects", pg_sum.stats.sum.num_objects);
}
f->close_section();
} else {
assert(ss != nullptr);
TextTable tbl;
tbl.define_column("SIZE", TextTable::LEFT, TextTable::RIGHT);
tbl.define_column("AVAIL", TextTable::LEFT, TextTable::RIGHT);
tbl.define_column("RAW USED", TextTable::LEFT, TextTable::RIGHT);
tbl.define_column("%RAW USED", TextTable::LEFT, TextTable::RIGHT);
if (verbose) {
tbl.define_column("OBJECTS", TextTable::LEFT, TextTable::RIGHT);
}
tbl << stringify(si_t(osd_sum.kb*1024))
<< stringify(si_t(osd_sum.kb_avail*1024))
<< stringify(si_t(osd_sum.kb_used*1024)