From 69b9e0472d99f7e5278b6579a2d73ffa83ecf1b1 Mon Sep 17 00:00:00 2001 From: David Zafman Date: Tue, 7 Jan 2020 17:39:11 -0800 Subject: [PATCH] mgr: Add pg_stats and pool_stats direct access More efficient to get just what you need out of the PGMap mgr/progress: Use pg_stats instead of pg_dump mgr/diskprediction_cloud: Use pg_stats instead of pg_dump mgr/balancer: Use pg_stats and pool_stats instead of pg_dump Fixes: https://tracker.ceph.com/issues/43556 Signed-off-by: David Zafman --- src/mgr/ActivePyModules.cc | 14 +++++++++ src/pybind/mgr/balancer/module.py | 31 +++++++++++-------- .../agent/metrics/ceph_cluster.py | 2 +- src/pybind/mgr/mgr_module.py | 3 +- src/pybind/mgr/progress/module.py | 8 ++--- src/pybind/mgr/selftest/module.py | 2 ++ 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/mgr/ActivePyModules.cc b/src/mgr/ActivePyModules.cc index b29a61459d8..10b7e0d4e2d 100644 --- a/src/mgr/ActivePyModules.cc +++ b/src/mgr/ActivePyModules.cc @@ -369,6 +369,20 @@ PyObject *ActivePyModules::get_python(const std::string &what) pg_map.dump_pool_stats_full(osd_map, nullptr, &f, true); }); return f.get(); + } else if (what == "pg_stats") { + cluster_state.with_pgmap( + [&f, &tstate](const PGMap &pg_map) { + PyEval_RestoreThread(tstate); + pg_map.dump_pg_stats(&f, false); + }); + return f.get(); + } else if (what == "pool_stats") { + cluster_state.with_pgmap( + [&f, &tstate](const PGMap &pg_map) { + PyEval_RestoreThread(tstate); + pg_map.dump_pool_stats(&f); + }); + return f.get(); } else if (what == "osd_stats") { cluster_state.with_pgmap( [&f, &tstate](const PGMap &pg_map) { diff --git a/src/pybind/mgr/balancer/module.py b/src/pybind/mgr/balancer/module.py index bbee82ee6a4..e70a7baee0f 100644 --- a/src/pybind/mgr/balancer/module.py +++ b/src/pybind/mgr/balancer/module.py @@ -1,4 +1,3 @@ - """ Balance PG distribution across OSDs. """ @@ -18,18 +17,19 @@ import datetime TIME_FORMAT = '%Y-%m-%d_%H:%M:%S' class MappingState: - def __init__(self, osdmap, pg_dump, desc=''): + def __init__(self, osdmap, raw_pg_stats, raw_pool_stats, desc=''): self.desc = desc self.osdmap = osdmap self.osdmap_dump = self.osdmap.dump() self.crush = osdmap.get_crush() self.crush_dump = self.crush.dump() - self.pg_dump = pg_dump + self.raw_pg_stats = raw_pg_stats + self.raw_pool_stats = raw_pool_stats self.pg_stat = { - i['pgid']: i['stat_sum'] for i in pg_dump.get('pg_stats', []) + i['pgid']: i['stat_sum'] for i in raw_pg_stats.get('pg_stats', []) } osd_poolids = [p['pool'] for p in self.osdmap_dump.get('pools', [])] - pg_poolids = [p['poolid'] for p in pg_dump.get('pool_stats', [])] + pg_poolids = [p['poolid'] for p in raw_pool_stats.get('pool_stats', [])] self.poolids = set(osd_poolids) & set(pg_poolids) self.pg_up = {} self.pg_up_by_poolid = {} @@ -72,7 +72,8 @@ class MsPlan(Plan): self.inc.set_osd_reweights(self.osd_weights) self.inc.set_crush_compat_weight_set_weights(self.compat_ws) return MappingState(self.initial.osdmap.apply_incremental(self.inc), - self.initial.pg_dump, + self.initial.raw_pg_stats, + self.initial.raw_pool_stats, 'plan %s final' % self.name) def dump(self): @@ -450,7 +451,8 @@ class Module(MgrModule): return (-errno.EPERM, '', warn) elif command['mode'] == 'crush-compat': ms = MappingState(self.get_osdmap(), - self.get("pg_dump"), + self.get("pg_stats"), + self.get("pool_stats"), 'initialize compat weight-set') self.get_compat_weight_set_weights(ms) # ignore error self.set_module_option('mode', command['mode']) @@ -527,7 +529,7 @@ class Module(MgrModule): if option not in valid_pool_names: return (-errno.EINVAL, '', 'option "%s" not a plan or a pool' % option) pools.append(option) - ms = MappingState(osdmap, self.get("pg_dump"), 'pool "%s"' % option) + ms = MappingState(osdmap, self.get("pg_stats"), self.get("pool_stats"), 'pool "%s"' % option) else: pools = plan.pools if plan.mode == 'upmap': @@ -535,16 +537,18 @@ class Module(MgrModule): # we use a basic version of Plan without keeping the obvious # *redundant* MS member. # Hence ms might not be accurate here since we are basically - # using an old snapshotted osdmap vs a fresh copy of pg_dump. + # using an old snapshotted osdmap vs a fresh copy of pg_stats. # It should not be a big deal though.. ms = MappingState(plan.osdmap, - self.get("pg_dump"), + self.get("pg_stats"), + self.get("pool_stats"), 'plan "%s"' % plan.name) else: ms = plan.final_state() else: ms = MappingState(self.get_osdmap(), - self.get("pg_dump"), + self.get("pg_stats"), + self.get("pool_stats"), 'current cluster') return (0, self.evaluate(ms, pools, verbose=verbose), '') elif command['prefix'] == 'balancer optimize': @@ -693,14 +697,15 @@ class Module(MgrModule): if mode == 'upmap': # drop unnecessary MS member for upmap mode. # this way we could effectively eliminate the usage of a - # complete pg_dump, which can become horribly inefficient + # complete pg_stats, which can become horribly inefficient # as pg_num grows.. plan = Plan(name, mode, osdmap, pools) else: plan = MsPlan(name, mode, MappingState(osdmap, - self.get("pg_dump"), + self.get("pg_stats"), + self.get("pool_stats"), 'plan %s initial' % name), pools) return plan diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py index 7c13d10afb4..2491644a89a 100644 --- a/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py @@ -89,7 +89,7 @@ class CephClusterAgent(MetricsAgent): else: c_data.fields['osd_bytes_used_percentage'] = 0.0000 - pg_stats = obj_api.module.get('pg_dump').get('pg_stats', []) + pg_stats = obj_api.module.get('pg_stats').get('pg_stats', []) num_bytes = 0 num_object = 0 num_object_degraded = 0 diff --git a/src/pybind/mgr/mgr_module.py b/src/pybind/mgr/mgr_module.py index 1681e7c998a..9186ca46035 100644 --- a/src/pybind/mgr/mgr_module.py +++ b/src/pybind/mgr/mgr_module.py @@ -795,7 +795,8 @@ class MgrModule(ceph_module.BaseMgrModule, MgrModuleLoggingMixin): :param str data_name: Valid things to fetch are osd_crush_map_text, osd_map, osd_map_tree, osd_map_crush, config, mon_map, fs_map, osd_metadata, pg_summary, io_rate, pg_dump, df, osd_stats, - health, mon_status, devices, device . + health, mon_status, devices, device , pg_stats, + pool_stats. Note: All these structures have their own JSON representations: experiment diff --git a/src/pybind/mgr/progress/module.py b/src/pybind/mgr/progress/module.py index c6ab2f9381a..89c097e5014 100644 --- a/src/pybind/mgr/progress/module.py +++ b/src/pybind/mgr/progress/module.py @@ -257,13 +257,13 @@ class PgRecoveryEvent(Event): def which_osds(self): return self. _which_osds - def pg_update(self, pg_dump, log): + def pg_update(self, raw_pg_stats, log): # type: (Dict, Any) -> None # FIXME: O(pg_num) in python # FIXME: far more fields getting pythonized than we really care about # Sanity check to see if there are any missing PGs and to assign # empty array and dictionary if there hasn't been any recovery - pg_to_state = dict([(p['pgid'], p) for p in pg_dump['pg_stats']]) # type: Dict[str, Any] + pg_to_state = dict([(p['pgid'], p) for p in raw_pg_stats['pg_stats']]) # type: Dict[str, Any] if self._original_bytes_recovered is None: self._original_bytes_recovered = {} missing_pgs = [] @@ -501,7 +501,7 @@ class Module(MgrModule): which_osds=[osd_id], start_epoch=self.get_osdmap().get_epoch() ) - r_ev.pg_update(self.get("pg_dump"), self.log) + r_ev.pg_update(self.get("pg_stats"), self.log) self._events[r_ev.id] = r_ev def _osdmap_changed(self, old_osdmap, new_osdmap): @@ -541,7 +541,7 @@ class Module(MgrModule): )) self._osdmap_changed(old_osdmap, self._latest_osdmap) elif notify_type == "pg_summary": - data = self.get("pg_dump") + data = self.get("pg_stats") for ev_id in list(self._events): ev = self._events[ev_id] if isinstance(ev, PgRecoveryEvent): diff --git a/src/pybind/mgr/selftest/module.py b/src/pybind/mgr/selftest/module.py index 7cf49f79efc..6f8c7118c11 100644 --- a/src/pybind/mgr/selftest/module.py +++ b/src/pybind/mgr/selftest/module.py @@ -238,6 +238,8 @@ class Module(MgrModule): "pg_status", "pg_dump", "df", + "pg_stats", + "pool_stats", "osd_stats", "health", "mon_status", -- 2.39.5