]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: calculate load by checking self CPU usage 23503/head
authorYan, Zheng <zyan@redhat.com>
Tue, 31 Jul 2018 03:32:02 +0000 (11:32 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 21 Aug 2018 08:45:51 +0000 (16:45 +0800)
when mds_bal_mode is 2, system CPU load is treated as mds load.
This is not good when the machine runs multiple tasks.

Fixes: http://tracker.ceph.com/issues/26834
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit 1ff36edd2a1827102e6196a9cba150fe866b7d43)

 Conflicts:
src/mds/MDBalancer.cc

src/mds/MDBalancer.cc
src/mds/MDBalancer.h

index e6bf839b218b0c8976754a17fe231d25e389a25a..deacf3678d88689403c7e13acac9cbfb7dc62e67 100644 (file)
@@ -233,33 +233,55 @@ mds_load_t MDBalancer::get_load(utime_t now)
   }
 
   uint64_t num_requests = mds->get_num_requests();
-  bool new_req_rate = false;
+
+  uint64_t cpu_time = 1;
+  {
+    string stat_path = PROCPREFIX "/proc/self/stat";
+    ifstream stat_file(stat_path);
+    if (stat_file.is_open()) {
+      vector<string> stat_vec(std::istream_iterator<string>{stat_file},
+                             std::istream_iterator<string>());
+      if (stat_vec.size() >= 15) {
+       // utime + stime
+       cpu_time = strtoll(stat_vec[13].c_str(), nullptr, 10) +
+                  strtoll(stat_vec[14].c_str(), nullptr, 10);
+      } else {
+       derr << "input file '" << stat_path << "' not resolvable" << dendl_impl;
+      }
+    } else {
+      derr << "input file '" << stat_path << "' not found" << dendl_impl;
+    }
+  }
+
+  load.queue_len = messenger->get_dispatch_queue_len();
+
+  bool update_last = true;
   if (last_get_load != utime_t() &&
-      now > last_get_load &&
-      num_requests >= last_num_requests) {
+      now > last_get_load) {
     utime_t el = now;
     el -= last_get_load;
     if (el.sec() >= 1) {
-      load.req_rate = (num_requests - last_num_requests) / (double)el;
-      new_req_rate = true;
+      if (num_requests > last_num_requests)
+       load.req_rate = (num_requests - last_num_requests) / (double)el;
+      if (cpu_time > last_cpu_time)
+       load.cpu_load_avg = (cpu_time - last_cpu_time) / (double)el;
+    } else {
+      auto p = mds_load.find(mds->get_nodeid());
+      if (p != mds_load.end()) {
+       load.req_rate = p->second.req_rate;
+       load.cpu_load_avg = p->second.cpu_load_avg;
+      }
+      if (num_requests >= last_num_requests && cpu_time >= last_cpu_time)
+       update_last = false;
     }
   }
-  if (!new_req_rate) {
-    auto p = mds_load.find(mds->get_nodeid());
-    if (p != mds_load.end())
-      load.req_rate = p->second.req_rate;
-  }
-  last_get_load = now;
-  last_num_requests = num_requests;
 
-  load.queue_len = messenger->get_dispatch_queue_len();
+  if (update_last) {
+    last_num_requests = num_requests;
+    last_cpu_time = cpu_time;
+    last_get_load = now;
+  }
 
-  ifstream cpu(PROCPREFIX "/proc/loadavg");
-  if (cpu.is_open())
-    cpu >> load.cpu_load_avg;
-  else
-    derr << "input file " PROCPREFIX "'/proc/loadavg' not found" << dendl_impl;
-  
   dout(15) << "get_load " << load << dendl;
   return load;
 }
index 3c842873aead776e08dbe0ac8000a8b045ddee0b..640c4404695b289913bd95f1d4f2367ad4c5fc28 100644 (file)
@@ -129,6 +129,7 @@ private:
 
   utime_t last_get_load;
   uint64_t last_num_requests = 0;
+  uint64_t last_cpu_time = 0;
 
   // Dirfrags which are marked to be passed on to MDCache::[split|merge]_dir
   // just as soon as a delayed context comes back and triggers it.