From a7f3108cc533734f7d73aa047e9ba5e7c4333087 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Sun, 22 Nov 2015 13:03:45 +0100 Subject: [PATCH] implement & document whashed 'sticky' server selection policy, as suggested by Winfried A. --- pdns/README-dnsdist.md | 5 ++++- pdns/dnsdist-lua.cc | 1 + pdns/dnsdist.cc | 16 +++++++++++++--- pdns/dnsdist.hh | 1 + 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 73840a614..3a9b7bdbe 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -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 diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index a6a7cd52b..21c920e34 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -275,6 +275,7 @@ vector> 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); }); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 24141f9d6..d745343c4 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -270,7 +270,7 @@ shared_ptr leastOutstanding(const NumberedServerVector& servers return poss.begin()->second; } -shared_ptr wrandom(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh) +shared_ptr valrandom(unsigned int val, const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh) { vector>> poss; int sum=0; @@ -278,7 +278,6 @@ shared_ptr 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 wrandom(const NumberedServerVector& servers, const C if(poss.empty()) return shared_ptr(); - 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(); return p->second; } +shared_ptr 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 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 roundrobin(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh) { NumberedServerVector poss; diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index f5d3ab780..9038de156 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -353,6 +353,7 @@ std::shared_ptr firstAvailable(const NumberedServerVector& serv std::shared_ptr leastOutstanding(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh); std::shared_ptr wrandom(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh); +std::shared_ptr whashed(const NumberedServerVector& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh); std::shared_ptr 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); -- 2.40.0