1 Loadbalancing and Server Policies
2 =================================
4 :program:`dnsdist` selects the server (if there are multiple eligible) to send queries to based on the configured policy.
5 Only servers that are marked as 'up', either forced so by the administrator or as the result of the last health check, might
14 The default load balancing policy is called ``leastOutstanding``, which means the server with the least queries 'in the air' is picked.
15 The exact selection algorithm is:
17 - pick the server with the least queries 'in the air' ;
18 - in case of a tie, pick the one with the lowest configured 'order' ;
19 - in case of a tie, pick the one with the lowest measured latency (over an average on the last 128 queries answered by that server).
24 The ``firstAvailable`` policy, picks the first available server that has not exceeded its QPS limit, ordered by increasing 'order'.
25 If all servers are above their QPS limit, a server is selected based on the ``leastOutstanding`` policy.
26 For now this is the only policy using the QPS limit.
31 A further policy, ``wrandom`` assigns queries randomly, but based on the weight parameter passed to :func:`newServer`.
33 For example, if two servers are available, the first one with a weight of 2 and the second one with a weight of 1 (the default), the
34 first one should get two-thirds of the incoming queries and the second one the remaining third.
39 ``whashed`` is a similar weighted policy, but assigns questions with identical hash to identical servers, allowing for better cache concentration ('sticky queries').
40 The current hash algorithm is based on the qname of the query.
42 .. function:: setWHashedPertubation(value)
44 Set the hash perturbation value to be used in the whashed policy instead of a random one, allowing to have consistent whashed results on different instances.
49 .. versionadded: 1.3.3
51 ``chashed`` is a consistent hashing distribution policy. Identical questions with identical hashes will be distributed to the same servers. But unlike the ``whashed`` policy, this distribution will keep consistent over time. Adding or removing servers will only remap a small part of the queries.
53 Increasing the weight of servers to a value larger than the default is required to get a good distribution of queries. Small values like 100 or 1000 should be enough to get a correct distribution.
54 This is a side-effect of the internal implementation of the consistent hashing algorithm, which assigns as many points on a circle to a server than its weight, and distributes a query to the server who has the closest point on the circle from the hash of the query's qname. Therefore having very few points, as is the case with the default weight of 1, leads to a poor distribution of queries.
56 You can also set the hash perturbation value, see :func:`setWHashedPertubation`. To achieve consistent distribution over :program:`dnsdist` restarts, you will also need to explicitly set the backend's UUIDs with the ``id`` option of :func:`newServer`. You can get the current UUIDs of your backends by calling :func:`showServers` with the ``showUUIDs=true`` option.
58 Since 1.5.0, a bounded-load version is also supported, preventing one server from receiving much more queries than the others, even if the distribution of queries is not perfect. This "consistent hashing with bounded loads" algorithm is enabled by setting :func:`setConsistentHashingBalancingFactor` to a value other than 0, which is the default. This value is the maximum number of outstanding queries that a given server can have at a given time, as a ratio of the average number of outstanding queries for all the active servers in the pool.
60 For example, setting :func:`setConsistentHashingBalancingFactor` to 1.5 means that no server will be allowed to have more outstanding queries than 1.5 times the average of all outstanding queries in the pool. The algorithm will try to select a server based on the hash of the qname, as is done when no bounded-load is set, but will disqualify all servers that have more outstanding queries than the average times the factor, until a suitable server is found.
61 The higher the factor, the more imbalance between the servers is allowed.
66 The last available policy is ``roundrobin``, which indiscriminately sends each query to the next server that is up.
67 If all servers are down, the policy will still select one server by default. Setting :func:`setRoundRobinFailOnNoServer` to ``true`` will change this behavior.
72 If you don't like the default policies you can create your own, like this for example::
75 function luaroundrobin(servers, dq)
77 return servers[1+(counter % #servers)]
80 setServerPolicyLua("luaroundrobin", luaroundrobin)
82 Incidentally, this is similar to setting: ``setServerPolicy(roundrobin)`` which uses the C++ based roundrobin policy.
86 newServer("192.168.1.2")
87 newServer({address="8.8.4.4", pool="numbered"})
89 function splitSetup(servers, dq)
90 if(string.match(dq.qname:toString(), "%d"))
92 print("numbered pool")
93 return leastOutstanding.policy(getPoolServers("numbered"), dq)
95 print("standard pool")
96 return leastOutstanding.policy(servers, dq)
100 setServerPolicyLua("splitsetup", splitSetup)
105 .. class:: ServerPolicy
107 This represents a server policy.
108 The built-in policies are of this type
110 .. function:: ServerPolicy.policy(servers, dq) -> Server
112 Run the policy to receive the server it has selected.
114 :param servers: A list of :class:`Server` objects
115 :param DNSQuestion dq: The incoming query
117 .. attribute:: ServerPolicy.ffipolicy
119 .. versionadded: 1.5.0
121 For policies implemented using the Lua FFI interface, the policy function itself.
123 .. attribute:: ServerPolicy.isFFI
125 .. versionadded: 1.5.0
127 Whether a Lua-based policy is implemented using the FFI interface.
129 .. attribute:: ServerPolicy.isLua
131 Whether this policy is a native (C++) policy or a Lua-based one.
133 .. attribute:: ServerPolicy.name
135 The name of the policy.
137 .. attribute:: ServerPolicy.policy
139 The policy function itself, except for FFI policies.
141 .. method:: Server:toString()
143 Return a textual representation of the policy.
149 .. function:: newServerPolicy(name, function) -> ServerPolicy
151 Create a policy object from a Lua function.
152 ``function`` must match the prototype for :func:`ServerPolicy.policy`.
154 :param string name: Name of the policy
155 :param string function: The function to call for this policy
157 .. function:: setConsistentHashingBalancingFactor(factor)
159 .. versionadded: 1.5.0
161 Set the maximum imbalance between the number of outstanding queries for a given server relative to the average number of outstanding queries for all servers in the pool,
162 when using the ``chashed`` consistent hashing load-balancing policy.
163 Default is 0, which disables the bounded-load algorithm.
165 .. function:: setServerPolicy(policy)
167 Set server selection policy to ``policy``.
169 :param ServerPolicy policy: The policy to use
171 .. function:: setServerPolicyLua(name, function)
173 Set server selection policy to one named ``name`` and provided by ``function``.
175 :param string name: name for this policy
176 :param string function: name of the function
178 .. function:: setServerPolicyLuaFFI(name, function)
180 .. versionadded:: 1.5.0
182 Set server selection policy to one named ``name`` and provided by the FFI function ``function``.
184 :param string name: name for this policy
185 :param string function: name of the FFI function
187 .. function:: setServFailWhenNoServer(value)
189 If set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query.
191 :param bool value: whether to return a servfail instead of dropping the query
193 .. function:: setPoolServerPolicy(policy, pool)
195 Set the server selection policy for ``pool`` to ``policy``.
197 :param ServerPolicy policy: The policy to apply
198 :param string pool: Name of the pool
200 .. function:: setPoolServerPolicyLua(name, function, pool)
202 Set the server selection policy for ``pool`` to one named ``name`` and provided by ``function``.
204 :param string name: name for this policy
205 :param string function: name of the function
206 :param string pool: Name of the pool
208 .. function:: setRoundRobinFailOnNoServer(value)
210 .. versionadded:: 1.4.0
212 By default the roundrobin load-balancing policy will still try to select a backend even if all backends are currently down. Setting this to true will make the policy fail and return that no server is available instead.
214 :param bool value: whether to fail when all servers are down
216 .. function:: showPoolServerPolicy(pool)
218 Print server selection policy for ``pool``.
220 :param string pool: The pool to print the policy for