]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: Add pg_stats and pool_stats direct access
authorDavid Zafman <dzafman@redhat.com>
Wed, 8 Jan 2020 01:39:11 +0000 (17:39 -0800)
committerDavid Zafman <dzafman@redhat.com>
Wed, 26 Feb 2020 19:59:53 +0000 (11:59 -0800)
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 <dzafman@redhat.com>
src/mgr/ActivePyModules.cc
src/pybind/mgr/balancer/module.py
src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py
src/pybind/mgr/mgr_module.py
src/pybind/mgr/progress/module.py
src/pybind/mgr/selftest/module.py

index b29a61459d8d3584245d45c11fa28d30a5c72fcc..10b7e0d4e2d5185656762e1fa8befa1289856b69 100644 (file)
@@ -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) {
index bbee82ee6a4e9ec05fbd0acede65ef37ec5af2fb..e70a7baee0f310763a664b6e14225af8d85a8b3e 100644 (file)
@@ -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
index 7c13d10afb42c006c0a9dda32bec742b5d673ced..2491644a89affc4378f756132e4510410a21247e 100644 (file)
@@ -89,7 +89,7 @@ class CephClusterAgent(MetricsAgent):
         else:\r
             c_data.fields['osd_bytes_used_percentage'] = 0.0000\r
 \r
-        pg_stats = obj_api.module.get('pg_dump').get('pg_stats', [])\r
+        pg_stats = obj_api.module.get('pg_stats').get('pg_stats', [])\r
         num_bytes = 0\r
         num_object = 0\r
         num_object_degraded = 0\r
index 1681e7c998ae3fcd17a8fc7a91c0d8eae61e4812..9186ca46035dd49e321508f2d55f86e179d9c456 100644 (file)
@@ -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 <devid>.
+                health, mon_status, devices, device <devid>, pg_stats,
+                pool_stats.
 
         Note:
             All these structures have their own JSON representations: experiment
index c6ab2f9381a86eca3f325c11049d79d69c41cadc..89c097e50143303679c58f2e46762b9158188cb0 100644 (file)
@@ -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):
index 7cf49f79efc2522f9477838cc0bb9380bea89c4d..6f8c7118c1118e4f73b90685c5b52d238ea20a5b 100644 (file)
@@ -238,6 +238,8 @@ class Module(MgrModule):
                 "pg_status",
                 "pg_dump",
                 "df",
+                "pg_stats",
+                "pool_stats",
                 "osd_stats",
                 "health",
                 "mon_status",