]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/balancer: pool-specific optimization for crush-compat
authorxie xingguo <xie.xingguo@zte.com.cn>
Tue, 30 Jan 2018 03:31:39 +0000 (11:31 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Thu, 1 Feb 2018 09:14:51 +0000 (17:14 +0800)
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/pybind/mgr/balancer/module.py

index f21805ba0e17cde787d87f5ca4636e3db041cefe..797a5e4eef9f778a5b1862019810799f4e5f8a1f 100644 (file)
@@ -287,17 +287,19 @@ class Module(MgrModule):
             return (0, '', '')
         elif command['prefix'] == 'balancer eval' or command['prefix'] == 'balancer eval-verbose':
             verbose = command['prefix'] == 'balancer eval-verbose'
+            pools = []
             if 'plan' in command:
                 plan = self.plans.get(command['plan'])
                 if not plan:
                     return (-errno.ENOENT, '', 'plan %s not found' %
                             command['plan'])
+                pools = plan.pools
                 ms = plan.final_state()
             else:
                 ms = MappingState(self.get_osdmap(),
                                   self.get("pg_dump"),
                                   'current cluster')
-            return (0, self.evaluate(ms, verbose=verbose), '')
+            return (0, self.evaluate(ms, pools, verbose=verbose), '')
         elif command['prefix'] == 'balancer optimize':
             pools = []
             if 'pools' in command:
@@ -387,18 +389,19 @@ class Module(MgrModule):
         if name in self.plans:
             del self.plans[name]
 
-    def calc_eval(self, ms):
+    def calc_eval(self, ms, pools):
         pe = Eval(ms)
         pool_rule = {}
         pool_info = {}
         for p in ms.osdmap_dump.get('pools',[]):
+            if len(pools) and p['pool_name'] not in pools:
+                continue
             pe.pool_name[p['pool']] = p['pool_name']
             pe.pool_id[p['pool_name']] = p['pool']
             pool_rule[p['pool_name']] = p['crush_rule']
             pe.pool_roots[p['pool_name']] = []
             pool_info[p['pool_name']] = p
-        pools = pe.pool_id.keys()
-        if len(pools) == 0:
+        if len(pool_info) == 0:
             return pe
         self.log.debug('pool_name %s' % pe.pool_name)
         self.log.debug('pool_id %s' % pe.pool_id)
@@ -413,14 +416,21 @@ class Module(MgrModule):
         rootids = ms.crush.find_takes()
         roots = []
         for rootid in rootids:
-            root = ms.crush.get_item_name(rootid)
-            pe.root_ids[root] = rootid
-            roots.append(root)
             ls = ms.osdmap.get_pools_by_take(rootid)
+            want = []
+            # find out roots associating with pools we are passed in
+            for candidate in ls:
+                if candidate in pe.pool_name:
+                    want.append(candidate)
+            if len(want) == 0:
+                continue
+            root = ms.crush.get_item_name(rootid)
             pe.root_pools[root] = []
-            for poolid in ls:
+            for poolid in want:
                 pe.pool_roots[pe.pool_name[poolid]].append(root)
                 pe.root_pools[root].append(pe.pool_name[poolid])
+            pe.root_ids[root] = rootid
+            roots.append(root)
             weight_map = ms.crush.get_take_weight_osd_map(rootid)
             adjusted_map = {
                 osd: cw * osd_weight.get(osd, 1.0)
@@ -558,6 +568,7 @@ class Module(MgrModule):
                 pe.total_by_root[a]
             ) for a, b in pe.count_by_root.iteritems()
         }
+        self.log.debug('stats_by_root %s' % pe.stats_by_root)
 
        # the scores are already normalized
         pe.score_by_root = {
@@ -567,6 +578,7 @@ class Module(MgrModule):
                 'bytes': pe.stats_by_root[r]['bytes']['score'],
             } for r in pe.total_by_root.keys()
         }
+        self.log.debug('score_by_root %s' % pe.score_by_root)
 
         # total score is just average of normalized stddevs
         pe.score = 0.0
@@ -576,8 +588,8 @@ class Module(MgrModule):
         pe.score /= 3 * len(roots)
         return pe
 
-    def evaluate(self, ms, verbose=False):
-        pe = self.calc_eval(ms)
+    def evaluate(self, ms, pools, verbose=False):
+        pe = self.calc_eval(ms, pools)
         return pe.show(verbose=verbose)
 
     def optimize(self, plan):
@@ -661,7 +673,7 @@ class Module(MgrModule):
         ms = plan.initial
         osdmap = ms.osdmap
         crush = osdmap.get_crush()
-        pe = self.calc_eval(ms)
+        pe = self.calc_eval(ms, plan.pools)
         if pe.score == 0:
             self.log.info('Distribution is already perfect')
             return False
@@ -768,7 +780,7 @@ class Module(MgrModule):
             # recalc
             plan.compat_ws = copy.deepcopy(next_ws)
             next_ms = plan.final_state()
-            next_pe = self.calc_eval(next_ms)
+            next_pe = self.calc_eval(next_ms, plan.pools)
             next_misplaced = next_ms.calc_misplaced_from(ms)
             self.log.debug('Step result score %f -> %f, misplacing %f',
                            best_pe.score, next_pe.score, next_misplaced)