]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: mds: optimize MDBalancer::try_rebalance()
authorYan, Zheng <zyan@redhat.com>
Tue, 3 Apr 2018 03:34:32 +0000 (11:34 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 10 Apr 2018 01:19:47 +0000 (09:19 +0800)
1. change import_pop_map to multimap because subtrees may have the same
   popularity.
2. avoid calculating subtrees' popularity multiple times

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/MDBalancer.cc

index 229092308eef7e3b3736b638a3d3ad54d3cb4d2a..ab20a91e6914fd177ab5c9079f0f97dfba6514c7 100644 (file)
@@ -820,8 +820,8 @@ void MDBalancer::try_rebalance(balance_state_t& state)
   }
 
   // make a sorted list of my imports
-  map<double,CDir*>    import_pop_map;
-  multimap<mds_rank_t,CDir*>  import_from_map;
+  multimap<double, CDir*> import_pop_map;
+  multimap<mds_rank_t, pair<CDir*, double> > import_from_map;
   set<CDir*> fullauthsubs;
 
   mds->mdcache->get_fullauth_subtrees(fullauthsubs);
@@ -829,6 +829,8 @@ void MDBalancer::try_rebalance(balance_state_t& state)
     CInode *diri = dir->get_inode();
     if (diri->is_mdsdir())
       continue;
+    if (dir->is_freezing() || dir->is_frozen())
+      continue;  // export pbly already in progress
 
     mds_rank_t from = diri->authority().first;
     double pop = dir->pop_auth_subtree.meta_load(rebalance_time, mds->mdcache->decayrate);
@@ -842,13 +844,11 @@ void MDBalancer::try_rebalance(balance_state_t& state)
       continue;
     }
 
-    import_pop_map[pop] = dir;
     dout(15) << "  map: i imported " << *dir << " from " << from << dendl;
-    import_from_map.insert(pair<mds_rank_t,CDir*>(from, dir));
+    import_pop_map.insert(make_pair(pop, dir));
+    import_from_map.insert(make_pair(from, make_pair(dir, pop)));
   }
 
-
-
   // do my exports!
   set<CDir*> already_exporting;
 
@@ -856,8 +856,10 @@ void MDBalancer::try_rebalance(balance_state_t& state)
     mds_rank_t target = it.first;
     double amount = it.second;
 
-    if (amount < MIN_OFFLOAD) continue;
-    if (amount / target_load < .2) continue;
+    if (amount / target_load < .2)
+      continue;
+    if (amount < MIN_OFFLOAD)
+      continue;
 
     dout(5) << "want to send " << amount << " to mds." << target
       //<< " .. " << (*it).second << " * " << load_fac
@@ -865,38 +867,41 @@ void MDBalancer::try_rebalance(balance_state_t& state)
            << dendl;//" .. fudge is " << fudge << dendl;
     double have = 0.0;
 
-
     mds->mdcache->show_subtrees();
 
     // search imports from target
     if (import_from_map.count(target)) {
       dout(5) << " aha, looking through imports from target mds." << target << dendl;
-      pair<multimap<mds_rank_t,CDir*>::iterator, multimap<mds_rank_t,CDir*>::iterator> p =
-       import_from_map.equal_range(target);
-      while (p.first != p.second) {
-       CDir *dir = (*p.first).second;
+      for (auto p = import_from_map.equal_range(target);
+          p.first != p.second; ) {
+       CDir *dir = p.first->second.first;
+       double pop = p.first->second.second;
        dout(5) << "considering " << *dir << " from " << (*p.first).first << dendl;
-       multimap<mds_rank_t,CDir*>::iterator plast = p.first++;
+       auto plast = p.first++;
 
        if (dir->inode->is_base())
          continue;
-       if (dir->is_freezing() || dir->is_frozen())
-         continue;  // export pbly already in progress
-       double pop = dir->pop_auth_subtree.meta_load(rebalance_time, mds->mdcache->decayrate);
        assert(dir->inode->authority().first == target);  // cuz that's how i put it in the map, dummy
 
        if (pop <= amount-have) {
-         dout(5) << "reexporting " << *dir
-                 << " pop " << pop
+         dout(5) << "reexporting " << *dir << " pop " << pop
                  << " back to mds." << target << dendl;
          mds->mdcache->migrator->export_dir_nicely(dir, target);
          have += pop;
          import_from_map.erase(plast);
-         import_pop_map.erase(pop);
+         for (auto q = import_pop_map.equal_range(pop);
+              q.first != q.second; ) {
+           if (q.first->second == dir) {
+             import_pop_map.erase(q.first);
+             break;
+           }
+           q.first++;
+         }
        } else {
          dout(5) << "can't reexport " << *dir << ", too big " << pop << dendl;
        }
-       if (amount-have < MIN_OFFLOAD) break;
+       if (amount-have < MIN_OFFLOAD)
+         break;
       }
     }
     if (amount-have < MIN_OFFLOAD) {
@@ -906,13 +911,12 @@ void MDBalancer::try_rebalance(balance_state_t& state)
     // okay, search for fragments of my workload
     list<CDir*> exports;
 
-    for (auto dir : fullauthsubs) {
-      if (dir->get_inode()->is_mdsdir())
-       continue;
-      if (dir->is_freezing() || dir->is_frozen())
-       continue;  // export pbly already in progress
+    for (auto p = import_pop_map.rbegin();
+        p != import_pop_map.rend();
+        ++p) {
+      CDir *dir = p->second;
       find_exports(dir, amount, exports, have, already_exporting);
-      if (have > amount-MIN_OFFLOAD)
+      if (amount-have < MIN_OFFLOAD)
        break;
     }
     //fudge = amount - have;