]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix request rate calculation
authorYan, Zheng <zyan@redhat.com>
Mon, 13 Nov 2017 09:22:33 +0000 (17:22 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 10 Apr 2018 01:19:29 +0000 (09:19 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Fixes: http://tracker.ceph.com/issues/21745
src/mds/MDBalancer.cc
src/mds/MDBalancer.h
src/mds/MDSRank.cc
src/mds/MDSRank.h

index dc0b784cb931bed91ef27121cf8fa9f8cd9182bb..6a8199aa90ffe485c47ba96fdba1ac0132cae53d 100644 (file)
@@ -167,8 +167,6 @@ void MDBalancer::tick()
   // We can use duration_cast below, although the result is an int,
   // because the values from g_conf are also integers.
   // balance?
-  if (mono_clock::is_zero(last_heartbeat))
-    last_heartbeat = now;
   if (mds->get_nodeid() == 0 &&
       g_conf->mds_bal_interval > 0 &&
       (num_bal_times ||
@@ -234,7 +232,26 @@ mds_load_t MDBalancer::get_load(utime_t now)
     dout(20) << "get_load no root, no load" << dendl;
   }
 
-  load.req_rate = mds->get_req_rate();
+  uint64_t num_requests = mds->get_num_requests();
+  bool new_req_rate = false;
+  if (last_get_load != utime_t() &&
+      now > last_get_load &&
+      num_requests >= last_num_requests) {
+    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 (!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();
 
   ifstream cpu(PROCPREFIX "/proc/loadavg");
@@ -307,12 +324,14 @@ void MDBalancer::send_heartbeat()
 
   if (mds->get_nodeid() == 0) {
     beat_epoch++;
-   
     mds_load.clear();
   }
 
   // my load
   mds_load_t load = get_load(now);
+  mds->logger->set(l_mds_load_cent, 100 * load.mds_load());
+  mds->logger->set(l_mds_dispatch_queue_len, load.queue_len);
+
   map<mds_rank_t, mds_load_t>::value_type val(mds->get_nodeid(), load);
   mds_load.insert(val);
 
@@ -385,12 +404,18 @@ void MDBalancer::handle_heartbeat(MHeartbeat *m)
   if (who == 0) {
     dout(20) << " from mds0, new epoch " << m->get_beat() << dendl;
     if (beat_epoch != m->get_beat()) {
+      beat_epoch = m->get_beat();
       mds_load.clear();
     }
-    beat_epoch = m->get_beat();
+
     send_heartbeat();
 
     mds->mdcache->show_subtrees();
+  } else if (mds->get_nodeid() == 0) {
+    if (beat_epoch != m->get_beat()) {
+      dout(10) << " old heartbeat epoch, ignoring" << dendl;
+      goto out;
+    }
   }
 
   {
index 72df1c6b6dcf57e84e1b2dccd93d48100a536b68..7254dee2f9dffcb61228b9540c03e176e5529b3d 100644 (file)
@@ -38,14 +38,7 @@ class MDBalancer {
   friend class C_Bal_SendHeartbeat;
 public:
   MDBalancer(MDSRank *m, Messenger *msgr, MonClient *monc) : 
-    mds(m),
-    messenger(msgr),
-    mon_client(monc),
-    beat_epoch(0),
-    last_epoch_under(0), my_load(0.0), target_load(0.0)
-    { }
-
-  mds_load_t get_load(utime_t);
+    mds(m), messenger(msgr), mon_client(monc) { }
 
   int proc_message(Message *m);
 
@@ -92,6 +85,8 @@ private:
   void handle_export_pins(void);
 
   void export_empties();
+
+  mds_load_t get_load(utime_t now);
   int localize_balancer();
   void send_heartbeat();
   void handle_heartbeat(MHeartbeat *m);
@@ -124,9 +119,9 @@ private:
   MDSRank *mds;
   Messenger *messenger;
   MonClient *mon_client;
-  int beat_epoch;
+  int beat_epoch = 0;
 
-  int last_epoch_under;
+  int last_epoch_under = 0;
   string bal_code;
   string bal_version;
 
@@ -134,6 +129,9 @@ private:
   mono_time last_sample = mono_clock::zero();
   utime_t rebalance_time; //ensure a consistent view of load for rebalance
 
+  utime_t last_get_load;
+  uint64_t last_num_requests = 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.
   // These sets just prevent us from spawning extra timer contexts for
@@ -147,7 +145,8 @@ private:
   map<mds_rank_t, int> mds_last_epoch_under_info;
 
   // per-epoch state
-  double          my_load, target_load;
+  double my_load = 0;
+  double target_load = 0;
 };
 
 #endif
index 8e7db126b7e3ef01a616f30a9a388416df1b3606..2e7ab6e2dbf62dd9fca2b88fac3de37838aa71f6 100644 (file)
@@ -266,11 +266,7 @@ void MDSRankDispatcher::tick()
   }
 
   // log
-  mds_load_t load = balancer->get_load(ceph_clock_now());
-
   if (logger) {
-    logger->set(l_mds_load_cent, 100 * load.mds_load());
-    logger->set(l_mds_dispatch_queue_len, messenger->get_dispatch_queue_len());
     logger->set(l_mds_subtrees, mdcache->num_subtrees());
 
     mdcache->log_stat();
index ff10dac6daad4a4327a7c6d79745c22e838b09b1..ef77333dff65e4bc744fdcb2971d9884879e86c9 100644 (file)
@@ -411,7 +411,7 @@ class MDSRank {
 
     MDSMap *get_mds_map() { return mdsmap; }
 
-    int get_req_rate() const { return logger->get(l_mds_request); }
+    uint64_t get_num_requests() const { return logger->get(l_mds_request); }
   
     int get_mds_slow_req_count() const { return mds_slow_req_count; }