]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: consistent hash - only pre compute when policy is set to chashed, lazy-load...
authorCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Tue, 19 Jun 2018 08:36:14 +0000 (10:36 +0200)
committerCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Tue, 19 Jun 2018 08:36:14 +0000 (10:36 +0200)
pdns/dnsdist.cc
pdns/dnsdist.hh

index 63789847af9d99f0a635230208a57d5a3019420a..a319d01f3782e9bce0d3a713f5b88d5c1d3a9b7a 100644 (file)
@@ -626,7 +626,9 @@ bool DownstreamState::reconnect()
 }
 void DownstreamState::hash()
 {
+  vinfolog("Computing hashes for id=%s and weight=%d", id, weight);
   auto w = weight;
+  WriteLock wl(&d_lock);
   hashes.clear();
   while (w > 0) {
     std::string uuid = boost::str(boost::format("%s-%d") % id % w);
@@ -639,17 +641,23 @@ void DownstreamState::hash()
 void DownstreamState::setId(const boost::uuids::uuid& newId)
 {
   id = newId;
-  hash();
+  // compute hashes only if already done
+  if (!hashes.empty()) {
+    hash();
+  }
 }
 
 void DownstreamState::setWeight(int newWeight)
 {
   weight = newWeight;
-  hash();
+  if (!hashes.empty()) {
+    hash();
+  }
 }
 
 DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, size_t numberOfSockets): remote(remote_), sourceAddr(sourceAddr_), sourceItf(sourceItf_)
 {
+  pthread_rwlock_init(&d_lock, nullptr);
   id = t_uuidGenerator();
   threadStarted.clear();
 
@@ -659,7 +667,6 @@ DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress
   for (auto& fd : sockets) {
     fd = -1;
   }
-  hash();
 
   if (!IsAnyAddress(remote)) {
     reconnect();
@@ -761,9 +768,15 @@ shared_ptr<DownstreamState> chashed(const NumberedServerVector& servers, const D
 
   for (const auto& d: servers) {
     if (d.second->isUp()) {
-      for (const auto& h: d.second->hashes) {
-        // put server's hashes on the circle
-        circle.insert(std::make_pair(h, d.second));
+      if (d.second->hashes.empty()) {
+        d.second->hash();
+      }
+      {
+        ReadLock rl(&(d.second->d_lock));
+        for (const auto& h: d.second->hashes) {
+          // put server's hashes on the circle
+          circle.insert(std::make_pair(h, d.second));
+        }
       }
     }
   }
@@ -2315,6 +2328,15 @@ try
 
   auto todo=setupLua(false, g_cmdLine.config);
 
+  if (g_policy.getLocal()->name == "chashed") {
+    vinfolog("Pre-computing hashes for consistent hash load-balancing policy");
+    // pre compute hashes
+    auto backends = g_dstates.getLocal();
+    for (auto& backend: *backends) {
+      backend->hash();
+    }
+  }
+
   if(g_cmdLine.locals.size()) {
     g_locals.clear();
     for(auto loc : g_cmdLine.locals)
index 0681812df93e0886df532e22dcf3cd64bf7c9ae4..6cda38c960661d9d2fcc11a41e000ee8f032ace9 100644 (file)
@@ -533,6 +533,7 @@ struct DownstreamState
   }
   boost::uuids::uuid id;
   std::set<unsigned int> hashes;
+  mutable pthread_rwlock_t d_lock;
   std::vector<int> sockets;
   std::mutex socketsLock;
   std::mutex connectLock;