]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/MonClient: implement weight-based mon selection
authorxie xingguo <xie.xingguo@zte.com.cn>
Sat, 16 Mar 2019 09:48:19 +0000 (17:48 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Wed, 20 Mar 2019 04:17:00 +0000 (12:17 +0800)
- first choose mon by priority, lowest first
- if there are still multiple targets, then choose them by their
  corresponding weight. If no customized or all zero weights specified,
  all targets will be selected at random.

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/mon/MonClient.cc

index bf4e12407594674b6f9a2967657e49b121a07b88..f514e7370f034949fb6d28c53a6deea74d2bf996 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <random>
+#include "common/weighted_shuffle.h"
 
 #include "include/scope_guard.h"
 #include "include/stringify.h"
@@ -687,21 +688,24 @@ MonConnection& MonClient::_add_conn(unsigned rank, uint64_t global_id)
 
 void MonClient::_add_conns(uint64_t global_id)
 {
-  uint16_t min_priority = std::numeric_limits<uint16_t>::max();
+  map<uint16_t, vector<unsigned>> rank_by_priority;
   for (const auto& m : monmap.mon_info) {
-    if (m.second.priority < min_priority) {
-      min_priority = m.second.priority;
-    }
+    rank_by_priority[m.second.priority].push_back(monmap.get_rank(m.first));
   }
   vector<unsigned> ranks;
-  for (const auto& m : monmap.mon_info) {
-    if (m.second.priority == min_priority) {
-      ranks.push_back(monmap.get_rank(m.first));
+  ceph_assert(!rank_by_priority.empty());
+  ranks = rank_by_priority.begin()->second;
+  if (ranks.size() > 1) {
+    vector<uint16_t> weights;
+    for (auto i : ranks) {
+      auto rank_name = monmap.get_name(i);
+      weights.push_back(monmap.get_weight(rank_name));
     }
+    std::random_device rd;
+    std::mt19937 gen(rd());
+    weighted_shuffle(ranks, weights, gen);
   }
-  std::random_device rd;
-  std::mt19937 rng(rd());
-  std::shuffle(ranks.begin(), ranks.end(), rng);
+  ldout(cct, 10) << __func__ << " ranks=" << ranks << dendl;
   unsigned n = cct->_conf->mon_client_hunt_parallel;
   if (n == 0 || n > ranks.size()) {
     n = ranks.size();