This repository has been archived by the owner on Jul 11, 2023. It is now read-only.
/
resty.dns.balancer.html
327 lines (257 loc) · 11.6 KB
/
resty.dns.balancer.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>DNS client for OpenResty</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>lua-resty-dns-client</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><strong>resty.dns.balancer</strong></li>
<li><a href="../modules/resty.dns.client.html">resty.dns.client</a></li>
<li><a href="../modules/resty.dns.utils.html">resty.dns.utils</a></li>
</ul>
<h2>Topics</h2>
<ul class="">
<li><a href="../topics/readme.md.html">readme</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.dns.balancer</code></h1>
<p>Ring-balancer.</p>
<p> This loadbalancer is designed for consistent hashing approaches and
to retain consistency on a maximum level while dealing with dynamic
changes like adding/removing hosts/targets.</p>
<p> Due to its deterministic way of operating it is also capable of running
identical balancers (identical consistent rings) on multiple servers/workers
(though it does not implement inter-server/worker communication).</p>
<p> Only dns is non-deterministic as it might occur when a peer is requested,
and hence should be avoided (by directly inserting ip addresses).
Adding/deleting hosts, etc (as long as done in the same order) is always
deterministic.</p>
<p> Updating the dns records is passive, meaning that when <a href="../modules/resty.dns.balancer.html#getPeer">getPeer</a> accesses a
target, only then the check is done whether the record is stale, and if so
it is updated. The one exception is the failed dns queries (because they
have no slots assigned, and hence will never be hit by <a href="../modules/resty.dns.balancer.html#getPeer">getPeer</a>), which will
be actively refreshed using a timer. </p>
<p> Whenever dns resolution fails for a hostname, the host will relinguish all
the slots it owns, and they will be reassigned to other targets.
Periodically the query for the hostname will be retried, and if it succeeds
it will get slots reassigned to it.</p>
<p> <strong>Housekeeping</strong>; the ring-balancer does some house keeping and may insert
some extra fields in dns records. Those fields will, similar to the <code>toip</code>
function, have an <code>__</code> prefix (double underscores).</p>
<h3>Info:</h3>
<ul>
<li><strong>Copyright</strong>: Mashape Inc. All rights reserved.</li>
<li><strong>License</strong>: Apache 2.0</li>
<li><strong>Author</strong>: Thijs Schreijer</li>
</ul>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#addHost">addHost (hostname, port, weight)</a></td>
<td class="summary">Adds a host to the balancer.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#getPeer">getPeer (hashValue, cacheOnly)</a></td>
<td class="summary">Gets the next ip address and port according to the loadbalancing scheme.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#new">new (opts)</a></td>
<td class="summary">Creates a new balancer.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#removeHost">removeHost (hostname, port)</a></td>
<td class="summary">Removes a host from a balancer.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "addHost"></a>
<strong>addHost (hostname, port, weight)</strong>
</dt>
<dd>
Adds a host to the balancer. If the name resolves to multiple entries,
each entry will be added, all with the same weight. So adding an A record
with 2 entries, with weight 10, will insert both entries with weight 10,
and increase to overall balancer weight by 20. The one exception is that if
it resolves to a record with <code>ttl=0</code>, then it will <strong>always</strong> only insert a single
(unresolved) entry. The unresolved entry will be resolved by <a href="../modules/resty.dns.balancer.html#getPeer">getPeer</a> when
requested.</p>
<p> Resolving will be done by the dns clients <code>resolve</code> method. Which will
dereference CNAME record if set to, but it will not dereference SRV records.
An unresolved SRV <code>target</code> field will also be resolved by <a href="../modules/resty.dns.balancer.html#getPeer">getPeer</a> when requested.</p>
<p> Only the slots assigned to the newly added targets will loose their
consistency, all other slots are guaranteed to remain the same.</p>
<p> Within a balancer the combination of <code>hostname</code> and <code>port</code> must be unique, so
multiple calls with the same target will only update the <code>weight</code> of the
existing entry.</p>
<p> <strong>multi-server/worker consistency</strong>; to keep multiple servers/workers consistent it is
important to apply all modifications to the ring-balancer in the exact same
order on each system. Also the initial <code>order</code> list must be the same. And; do
not use names, only ip adresses, as dns resolution is non-deterministic
across servers/workers.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">hostname</span>
hostname to add (note: not validated, as long as it’s a
string it will be accepted, but remain unresolved!)
</li>
<li><span class="parameter">port</span>
(optional) the port to use (defaults to 80 if omitted)
</li>
<li><span class="parameter">weight</span>
(optional) relative weight for A/AAAA records (defaults to
10 if omitted), and will be ignored in case of an SRV record.
</li>
</ul>
<h3>Returns:</h3>
<ol>
balancer object, or throw an error on bad input
</ol>
</dd>
<dt>
<a name = "getPeer"></a>
<strong>getPeer (hashValue, cacheOnly)</strong>
</dt>
<dd>
Gets the next ip address and port according to the loadbalancing scheme.
If the dns record attached to the requested slot is expired, then it will
be renewed and as a consequence the ring-balancer might be updated.</p>
<p> If the slot that is requested holds either an unresolved SRV entry (where
the <code>target</code> field contains a name instead of an ip), or a record with <code>ttl=0</code> then
this call will perform the final query to resolve to an ip using the <code>toip</code>
function of the dns client (this also invokes the loadbalancing as done by
the <code>toip</code> function).
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">hashValue</span>
(optional) number for consistent hashing, round-robins if
omitted. The hashValue can be an integer from 1 to <code>wheelSize</code>, or a float
from 0 up to, but not including, 1.
</li>
<li><span class="parameter">cacheOnly</span>
If truthy, no dns lookups will be done, only cache.
</li>
</ul>
<h3>Returns:</h3>
<ol>
<code>ip + port + hostname</code>, or <code>nil+error</code>
</ol>
</dd>
<dt>
<a name = "new"></a>
<strong>new (opts)</strong>
</dt>
<dd>
<p>Creates a new balancer. The balancer is based on a wheel with slots. The
slots will be randomly distributed over the targets. The number of slots
assigned will be relative to the weight.</p>
<p> A single balancer can hold multiple hosts. A host can be an ip address or a
name. As such each host can have multiple targets (or actual ip+port
combinations).</p>
<p> The options table has the following fields;</p>
<ul>
<li><code>hosts</code> (optional) containing hostnames, ports and weights. If omitted,
ports and weights default respectively to 80 and 10. The list will be sorted
before being added, so the order of entry is deterministic.</li>
<li><code>wheelSize</code> (optional) for total number of slots in the balancer, if omitted
the size of <code>order</code> is used, or 1000 if <code>order</code> is not provided. It is important
to have enough slots to keep the ring properly randomly distributed. If there
are to few slots for the number of targets then the load distribution might
become to coarse. Consider the maximum number of targets expected, as new
hosts can be dynamically added, and dns renewals might yield larger record
sets. The <code>wheelSize</code> cannot be altered, only a new wheel can be created, but
then all consistency would be lost. On a similar note; making it too big,
will have a performance impact when the wheel is modified as too many slots
will have to be moved between targets. A value of 50 to 200 slots per entry
seems about right.</li>
<li><code>order</code> (optional) if given, a list of random numbers, size <code>wheelSize</code>, used to
randomize the wheel. This entry is solely to support multiple servers with
the same consistency, as it allows to use the same randomization on each
server, and hence the same slot assignment. Duplicates are not allowed in
the list.</li>
<li><code>dns</code> (required) a configured <a href="../modules/resty.dns.client.html">dns.client</a> object for querying the dns server.</li>
<li><code>requery</code> (optional) interval of requerying the dns server for previously
failed queries. Defaults to 1 if omitted (in seconds)</li>
<li><code>ttl0</code> (optional) Maximum lifetime for records inserted with ttl=0, to verify
the ttl is still 0. Defaults to 60 if omitted (in seconds)</li>
</ul>
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">opts</span>
table with options
</li>
</ul>
<h3>Returns:</h3>
<ol>
new balancer object or nil+error
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="comment">-- hosts
</span><span class="keyword">local</span> hosts = {
<span class="string">"mashape.com"</span>, <span class="comment">-- name only, as string
</span> { name = <span class="string">"gelato.io"</span> }, <span class="comment">-- name only, as table
</span> { name = <span class="string">"getkong.org"</span>, port = <span class="number">80</span>, weight = <span class="number">25</span> }, <span class="comment">-- fully specified, as table
</span>}</pre>
</ul>
</dd>
<dt>
<a name = "removeHost"></a>
<strong>removeHost (hostname, port)</strong>
</dt>
<dd>
Removes a host from a balancer. All assigned slots will be redistributed
to the remaining targets. Only the slots from the removed host will loose
their consistency, all other slots are guaranteed to remain in place.
Will not throw an error if the hostname is not in the current list.</p>
<p> See <a href="../modules/resty.dns.balancer.html#addHost">addHost</a> for multi-server consistency.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">hostname</span>
hostname to remove
</li>
<li><span class="parameter">port</span>
port to remove (optional, defaults to 80 if omitted)
</li>
</ul>
<h3>Returns:</h3>
<ol>
balancer object, or an error on bad input
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.5</a></i>
<i style="float:right;">Last updated 2016-11-08 21:54:44 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>