From: Sage Weil Date: Thu, 10 Mar 2016 13:30:45 +0000 (-0500) Subject: osd/OSDMap: add summarize_mapping_stats X-Git-Tag: v0.94.7~10^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=94134d9148edfcc41d2d239db69d0b299fbf427f;p=ceph.git osd/OSDMap: add summarize_mapping_stats Calculate some basic stats about the PG distribution. Signed-off-by: Sage Weil (cherry picked from commit ea9abe53d0e777b7dc3b22af71639f77c4de08c8) - remove c++11 auto and range-based for loops --- diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc index 173b468b5b0e..2bb1263a50f2 100644 --- a/src/osd/OSDMap.cc +++ b/src/osd/OSDMap.cc @@ -2873,3 +2873,168 @@ int OSDMap::build_simple_crush_rulesets(CephContext *cct, // require the crush_v2 feature of clients return 0; } + +int OSDMap::summarize_mapping_stats( + OSDMap *newmap, + const set *pools, + std::string *out, + Formatter *f) const +{ + set ls; + if (pools) { + ls = *pools; + } else { + for (map::const_iterator i = get_pools().begin(); + i != get_pools().end(); + ++i) { + ls.insert(i->first); + } + } + + unsigned total_pg = 0; + unsigned moved_pg = 0; + vector base_by_osd(get_max_osd(), 0); + vector new_by_osd(get_max_osd(), 0); + for (set::iterator p = ls.begin(); p != ls.end(); ++p) { + int64_t pool_id = *p; + const pg_pool_t *pi = get_pg_pool(pool_id); + vector up, up2, acting; + int up_primary, acting_primary; + for (unsigned ps = 0; ps < pi->get_pg_num(); ++ps) { + pg_t pgid(ps, pool_id, -1); + total_pg += pi->get_size(); + pg_to_up_acting_osds(pgid, &up, &up_primary, + &acting, &acting_primary); + for (vector::iterator q = up.begin(); q != up.end(); ++q) { + int osd = *q; + if (osd >= 0 && osd < get_max_osd()) + ++base_by_osd[osd]; + } + if (newmap) { + newmap->pg_to_up_acting_osds(pgid, &up2, &up_primary, + &acting, &acting_primary); + for (vector::iterator q = up2.begin(); q != up2.end(); ++q) { + int osd = *q; + if (osd >= 0 && osd < get_max_osd()) + ++new_by_osd[osd]; + } + if (pi->type == pg_pool_t::TYPE_ERASURE) { + for (unsigned i=0; itype == pg_pool_t::TYPE_REPLICATED) { + for (vector::iterator q = up.begin(); q != up.end(); ++q) { + int osd = *q; + if (std::find(up2.begin(), up2.end(), osd) == up2.end()) { + ++moved_pg; + } + } + } else { + assert(0 == "unhandled pool type"); + } + } + } + } + + unsigned num_up_in = 0; + for (int osd = 0; osd < get_max_osd(); ++osd) { + if (is_up(osd) && is_in(osd)) + ++num_up_in; + } + if (!num_up_in) { + return -EINVAL; + } + + float avg_pg = (float)total_pg / (float)num_up_in; + float base_stddev = 0, new_stddev = 0; + int min = -1, max = -1; + unsigned min_base_pg = 0, max_base_pg = 0; + unsigned min_new_pg = 0, max_new_pg = 0; + for (int osd = 0; osd < get_max_osd(); ++osd) { + if (is_up(osd) && is_in(osd)) { + float base_diff = (float)base_by_osd[osd] - avg_pg; + base_stddev += base_diff * base_diff; + float new_diff = (float)new_by_osd[osd] - avg_pg; + new_stddev += new_diff * new_diff; + if (min < 0 || min_base_pg < base_by_osd[osd]) { + min = osd; + min_base_pg = base_by_osd[osd]; + min_new_pg = new_by_osd[osd]; + } + if (max < 0 || max_base_pg > base_by_osd[osd]) { + max = osd; + max_base_pg = base_by_osd[osd]; + max_new_pg = new_by_osd[osd]; + } + } + } + base_stddev = sqrt(base_stddev / num_up_in); + new_stddev = sqrt(new_stddev / num_up_in); + + float edev = sqrt(avg_pg * (1.0 - (1.0 / (double)num_up_in))); + + ostringstream ss; + if (f) + f->open_object_section("utilization"); + if (newmap) { + if (f) { + f->dump_unsigned("moved_pgs", moved_pg); + f->dump_unsigned("total_pgs", total_pg); + } else { + ss << "moved " << moved_pg << " / " << total_pg + << " (" << ((float)moved_pg * 100.0 / (float)total_pg) << "%)\n"; + } + } + if (f) { + f->dump_float("avg_pgs", avg_pg); + f->dump_float("std_dev", base_stddev); + f->dump_float("expected_baseline_std_dev", edev); + if (newmap) + f->dump_float("new_std_dev", new_stddev); + } else { + ss << "avg " << avg_pg << "\n"; + ss << "stddev " << base_stddev; + if (newmap) + ss << " -> " << new_stddev; + ss << " (expected baseline " << edev << ")\n"; + } + if (min >= 0) { + if (f) { + f->dump_unsigned("min_osd", min); + f->dump_unsigned("min_osd_pgs", min_base_pg); + if (newmap) + f->dump_unsigned("new_min_osd_pgs", min_new_pg); + } else { + ss << "min osd." << min << " with " << min_base_pg; + if (newmap) + ss << " -> " << min_new_pg; + ss << " pgs (" << (float)min_base_pg / avg_pg; + if (newmap) + ss << " -> " << (float)min_new_pg / avg_pg; + ss << " * mean)\n"; + } + } + if (max >= 0) { + if (f) { + f->dump_unsigned("max_osd", max); + f->dump_unsigned("max_osd_pgs", max_base_pg); + if (newmap) + f->dump_unsigned("new_max_osd_pgs", max_new_pg); + } else { + ss << "max osd." << min << " with " << max_base_pg; + if (newmap) + ss << " -> " << max_new_pg; + ss << " pgs (" << (float)max_base_pg / avg_pg; + if (newmap) + ss << " -> " << (float)max_new_pg / avg_pg; + ss << " * mean)\n"; + } + } + if (f) + f->close_section(); + if (out) + *out = ss.str(); + return 0; +} diff --git a/src/osd/OSDMap.h b/src/osd/OSDMap.h index 24991195c356..272bd7d02a51 100644 --- a/src/osd/OSDMap.h +++ b/src/osd/OSDMap.h @@ -860,6 +860,12 @@ public: void print_oneline_summary(ostream& out) const; void print_tree(ostream *out, Formatter *f) const; + int summarize_mapping_stats( + OSDMap *newmap, + const set *pools, + std::string *out, + Formatter *f) const; + string get_flag_string() const; static string get_flag_string(unsigned flags); static void dump_erasure_code_profiles(const map > &profiles,