]> granicus.if.org Git - pdns/commitdiff
implement & document whashed 'sticky' server selection policy, as suggested by Winfri...
authorbert hubert <bert.hubert@netherlabs.nl>
Sun, 22 Nov 2015 12:03:45 +0000 (13:03 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Sun, 22 Nov 2015 12:03:45 +0000 (13:03 +0100)
pdns/README-dnsdist.md
pdns/dnsdist-lua.cc
pdns/dnsdist.cc
pdns/dnsdist.hh

index 73840a61401bd622722b88641a54778826d805a9..3a9b7bdbe1d232e54d71b0aadb83e7c2e1af33ec 100644 (file)
@@ -428,7 +428,9 @@ Another policy, 'firstAvailable', picks the first server that has not
 exceeded its QPS limit gets the traffic.  
 
 A further policy, 'wrandom' assigns queries randomly, but based on the
-'weight' parameter passed to `newServer` 
+'weight' parameter passed to `newServer`. `whashed` is a similar weighted policy,
+but assigns questions with identical hash to identical servers, allowing for
+better cache concentration ('sticky queries').
 
 If you don't like the default policies you can create your own, like this
 for example:
@@ -630,6 +632,7 @@ instantiate a server with additional parameters
    * `newServerPolicy(name, function)`: create a policy object from a Lua function
  * Available policies:
    * `firstAvailable`: Pick first server that has not exceeded its QPS limit, ordered by the server 'order' parameter
+   * `whashed`: Weighted hashed ('sticky') distribution over available servers, based on the server 'weight' parameter
    * `wrandom`: Weighted random over available servers, based on the server 'weight' parameter
    * `roundrobin`: Simple round robin over available servers
    * `leastOutstanding`: Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency
index a6a7cd52ba49c93f7afb2502028bbff24365ce23..21c920e34bda308f22b0c7a658c6c90a3fec7a1d 100644 (file)
@@ -275,6 +275,7 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
   g_lua.writeVariable("firstAvailable", ServerPolicy{"firstAvailable", firstAvailable});
   g_lua.writeVariable("roundrobin", ServerPolicy{"roundrobin", roundrobin});
   g_lua.writeVariable("wrandom", ServerPolicy{"wrandom", wrandom});
+  g_lua.writeVariable("whashed", ServerPolicy{"whashed", whashed});
   g_lua.writeVariable("leastOutstanding", ServerPolicy{"leastOutstanding", leastOutstanding});
   g_lua.writeFunction("addACL", [](const std::string& domain) {
       g_ACL.modify([domain](NetmaskGroup& nmg) { nmg.addMask(domain); });
index 24141f9d6d8c2505b6aec0d5149069cfe2e9d7e8..d745343c4f276966fac9af34dcbeda81bf02ad61 100644 (file)
@@ -270,7 +270,7 @@ shared_ptr<DownstreamState> leastOutstanding(const NumberedServerVector& servers
   return poss.begin()->second;
 }
 
-shared_ptr<DownstreamState> wrandom(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh)
+shared_ptr<DownstreamState> valrandom(unsigned int val, const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh)
 {
   vector<pair<int, shared_ptr<DownstreamState>>> poss;
   int sum=0;
@@ -278,7 +278,6 @@ shared_ptr<DownstreamState> wrandom(const NumberedServerVector& servers, const C
     if(d.second->isUp()) {
       sum+=d.second->weight;
       poss.push_back({sum, d.second});
-
     }
   }
 
@@ -286,13 +285,24 @@ shared_ptr<DownstreamState> wrandom(const NumberedServerVector& servers, const C
   if(poss.empty())
     return shared_ptr<DownstreamState>();
 
-  int r = random() % sum;
+  int r = val % sum;
   auto p = upper_bound(poss.begin(), poss.end(),r, [](int r, const decltype(poss)::value_type& a) { return  r < a.first;});
   if(p==poss.end())
     return shared_ptr<DownstreamState>();
   return p->second;
 }
 
+shared_ptr<DownstreamState> wrandom(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh)
+{
+  return valrandom(random(), servers, remote, qname, qtype, dh);
+}
+
+shared_ptr<DownstreamState> whashed(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh)
+{
+  return valrandom(qname.hash(), servers, remote, qname, qtype, dh);
+}
+
+
 shared_ptr<DownstreamState> roundrobin(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh)
 {
   NumberedServerVector poss;
index f5d3ab7803b58f9a8f51a71486f9db4b44d8d645..9038de1565ff45d03d6aad474299558eba1498e6 100644 (file)
@@ -353,6 +353,7 @@ std::shared_ptr<DownstreamState> firstAvailable(const NumberedServerVector& serv
 
 std::shared_ptr<DownstreamState> leastOutstanding(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh);
 std::shared_ptr<DownstreamState> wrandom(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh);
+std::shared_ptr<DownstreamState> whashed(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh);
 std::shared_ptr<DownstreamState> roundrobin(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh);
 int getEDNSZ(const char* packet, unsigned int len);
 void dnsdistWebserverThread(int sock, const ComboAddress& local, const string& password);