]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsdistdist/docs/guides/serverselection.rst
Merge pull request #8505 from rgacogne/dnsdist-lua-ffi
[thirdparty/pdns.git] / pdns / dnsdistdist / docs / guides / serverselection.rst
1 Loadbalancing and Server Policies
2 =================================
3
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
6 be selected.
7
8 Built-in Policies
9 -----------------
10
11 ``leastOutstanding``
12 ~~~~~~~~~~~~~~~~~~~~
13
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:
16
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).
20
21 ``firstAvailable``
22 ~~~~~~~~~~~~~~~~~~
23
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.
27
28 ``wrandom``
29 ~~~~~~~~~~~
30
31 A further policy, ``wrandom`` assigns queries randomly, but based on the weight parameter passed to :func:`newServer`.
32
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.
35
36 ``whashed``
37 ~~~~~~~~~~~
38
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.
41
42 .. function:: setWHashedPertubation(value)
43
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.
45
46 ``chashed``
47 ~~~~~~~~~~~
48
49 .. versionadded: 1.3.3
50
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.
52
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.
55
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.
57
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.
59
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.
62
63 ``roundrobin``
64 ~~~~~~~~~~~~~~
65
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.
68
69 Lua server policies
70 -------------------
71
72 If you don't like the default policies you can create your own, like this for example::
73
74 counter=0
75 function luaroundrobin(servers, dq)
76 counter=counter+1
77 return servers[1+(counter % #servers)]
78 end
79
80 setServerPolicyLua("luaroundrobin", luaroundrobin)
81
82 Incidentally, this is similar to setting: ``setServerPolicy(roundrobin)`` which uses the C++ based roundrobin policy.
83
84 Or::
85
86 newServer("192.168.1.2")
87 newServer({address="8.8.4.4", pool="numbered"})
88
89 function splitSetup(servers, dq)
90 if(string.match(dq.qname:toString(), "%d"))
91 then
92 print("numbered pool")
93 return leastOutstanding.policy(getPoolServers("numbered"), dq)
94 else
95 print("standard pool")
96 return leastOutstanding.policy(servers, dq)
97 end
98 end
99
100 setServerPolicyLua("splitsetup", splitSetup)
101
102 ServerPolicy Objects
103 --------------------
104
105 .. class:: ServerPolicy
106
107 This represents a server policy.
108 The built-in policies are of this type
109
110 .. function:: ServerPolicy.policy(servers, dq) -> Server
111
112 Run the policy to receive the server it has selected.
113
114 :param servers: A list of :class:`Server` objects
115 :param DNSQuestion dq: The incoming query
116
117 .. attribute:: ServerPolicy.ffipolicy
118
119 .. versionadded: 1.5.0
120
121 For policies implemented using the Lua FFI interface, the policy function itself.
122
123 .. attribute:: ServerPolicy.isFFI
124
125 .. versionadded: 1.5.0
126
127 Whether a Lua-based policy is implemented using the FFI interface.
128
129 .. attribute:: ServerPolicy.isLua
130
131 Whether this policy is a native (C++) policy or a Lua-based one.
132
133 .. attribute:: ServerPolicy.name
134
135 The name of the policy.
136
137 .. attribute:: ServerPolicy.policy
138
139 The policy function itself, except for FFI policies.
140
141 .. method:: Server:toString()
142
143 Return a textual representation of the policy.
144
145
146 Functions
147 ---------
148
149 .. function:: newServerPolicy(name, function) -> ServerPolicy
150
151 Create a policy object from a Lua function.
152 ``function`` must match the prototype for :func:`ServerPolicy.policy`.
153
154 :param string name: Name of the policy
155 :param string function: The function to call for this policy
156
157 .. function:: setConsistentHashingBalancingFactor(factor)
158
159 .. versionadded: 1.5.0
160
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.
164
165 .. function:: setServerPolicy(policy)
166
167 Set server selection policy to ``policy``.
168
169 :param ServerPolicy policy: The policy to use
170
171 .. function:: setServerPolicyLua(name, function)
172
173 Set server selection policy to one named ``name`` and provided by ``function``.
174
175 :param string name: name for this policy
176 :param string function: name of the function
177
178 .. function:: setServerPolicyLuaFFI(name, function)
179
180 .. versionadded:: 1.5.0
181
182 Set server selection policy to one named ``name`` and provided by the FFI function ``function``.
183
184 :param string name: name for this policy
185 :param string function: name of the FFI function
186
187 .. function:: setServFailWhenNoServer(value)
188
189 If set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query.
190
191 :param bool value: whether to return a servfail instead of dropping the query
192
193 .. function:: setPoolServerPolicy(policy, pool)
194
195 Set the server selection policy for ``pool`` to ``policy``.
196
197 :param ServerPolicy policy: The policy to apply
198 :param string pool: Name of the pool
199
200 .. function:: setPoolServerPolicyLua(name, function, pool)
201
202 Set the server selection policy for ``pool`` to one named ``name`` and provided by ``function``.
203
204 :param string name: name for this policy
205 :param string function: name of the function
206 :param string pool: Name of the pool
207
208 .. function:: setRoundRobinFailOnNoServer(value)
209
210 .. versionadded:: 1.4.0
211
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.
213
214 :param bool value: whether to fail when all servers are down
215
216 .. function:: showPoolServerPolicy(pool)
217
218 Print server selection policy for ``pool``.
219
220 :param string pool: The pool to print the policy for