10.7 Round Robin Load Distribution
Name servers released
since BIND 4.9 have formalized some load distribution functionality
that has existed in patches to BIND for some time. Bryan
Beecher wrote
patches to BIND 4.8.3 to implement what he called
"shuffle address records." These
were address records of a special type that the name server rotated
between responses. For example, if the domain name
foo.bar.baz had three "shuffled" IP
addresses, 192.168.1.1, 192.168.1.2, and 192.1.168.3, an
appropriately patched name server would give them out first in the
order:
192.168.1.1 192.168.1.2 192.168.1.3
then in the order:
192.168.1.2 192.168.1.3 192.168.1.1
and then in the order:
192.168.1.3 192.168.1.1 192.168.1.2
before starting all over with the first order and repeating the
rotation ad infinitum.
The functionality is enormously useful if you have a number of
equivalent network resources, such as mirrored FTP servers, web
servers, or terminal servers, and you'd like to spread the load
among them. You establish one domain name that refers to the group of
resources and configure clients to access that domain name, and the
name server distributes requests among the IP addresses you list.
BIND 4.9 and later versions do away with the shuffle address record
as a separate record type, subject to special handling. Instead, a
modern name server rotates addresses for any domain name that has
more than one A record. (In fact, the name server will rotate any
type of record as long as a given domain name has more than one of
them. ) So the records:
foo.bar.baz. 60 IN A 192.168.1.1
foo.bar.baz. 60 IN A 192.168.1.2
foo.bar.baz. 60 IN A 192.168.1.3
accomplish on a 4.9 or later name server just what the shuffle
address records did on a patched 4.8.3 server. The BIND documentation
calls this process round robin.
It's a good
idea to reduce the records' time to live, too, as we did in this
example. This ensures that if the addresses are cached on an
intermediate name server that doesn't support round robin,
they'll time out of the cache quickly. If the intermediate name
server looks up the name again, your authoritative name server can
round robin the addresses again.
Note that this is really load distribution, not load balancing, since
the name server gives out the addresses in a completely deterministic
way without regard to the actual load or capacity of the servers
servicing the requests. In our example, the server at address
192.168.1.3 could be a 486DX33 running Linux and the other two
servers HP9000 Superdomes, and the Linux box would still get a third
of the queries. Listing a higher-capacity server's address
multiple times won't help because BIND eliminates duplicate
records.
10.7.1 Multiple CNAMEs
Back in the heyday of BIND 4 name servers, some folks set up round
robin using multiple CNAME records instead of
multiple address records:
foo1.bar.baz. 60 IN A 192.168.1.1
foo2.bar.baz. 60 IN A 192.168.1.2
foo3.bar.baz. 60 IN A 192.168.1.3
foo.bar.baz. 60 IN CNAME foo1.bar.baz.
foo.bar.baz. 60 IN CNAME foo2.bar.baz.
foo.bar.baz. 60 IN CNAME foo3.bar.baz.
This probably looks odd to those of you who are used to our harping
on the evils of mixing anything with a CNAME record. But BIND 4 name
servers didn't recognize this as the configuration error it is
and simply returned the CNAME records for foo.bar.baz
in round robin order.
BIND 8 name servers, on the other hand, are more vigilant and catch
this error. You can, however, explicitly configure them to allow
multiple CNAME records for a single domain name with:
options {
multiple-cnames yes;
};
BIND 9 name servers don't notice the multiple CNAME problem
until 9.1.0. BIND 9.1.0 detects the problem but doesn't support
the
multiple-cnames statement.
10.7.2 The rrset-order Substatement
There are certain times when
you'd rather the name server didn't use round robin. For
example, maybe you'd like to designate one web server as a
backup to another. To do this, the
name server should always return the
backup's address after the primary web server's address.
But you can't do that with round robin; it'll just rotate
the order of the addresses in successive responses.
BIND 8.2 and later name servers—but not BIND 9 name servers, as
of 9.1.0—allow you to turn off round robin for certain domain
names and types of records. For example, if we wanted to ensure that
the address records for www.movie.edu were
always returned in the same order, we could use this
rrset-order substatement:
options {
rrset-order {
class IN type A name "www.movie.edu" order fixed;
};
};
We should probably lower the TTL on
www.movie.edu's address records, too, so a
name server that cached the records wouldn't round robin them
for long.
The class, type, and
name settings determine which records the
specified order applies to. The class defaults to IN, type to ANY,
and name to * —in other words, any records. So the statement:
options {
rrset-order {
order random;
};
};
applies a random order to all records returned by the name server.
The name setting may contain a wildcard as its leftmost label, as in:
options {
rrset-order {
type A name "*.movie.edu" order cyclic;
};
};
Only one rrset-order substatement is permitted,
but it can contain multiple order specifications. The first order
specification to match a set of records in a response applies.
rrset-order supports three (count 'em,
three!) different orders:
- fixed
Always return matching records in the same order
- random
Return matching records in random order
- cyclic
Return matching records in cyclic (round robin) order
The default behavior is:
options {
rrset-order {
class IN type ANY name "*" order cyclic;
};
};
Configuring rrset-order is far from a complete
solution, unfortunately, because resolver and name server caching can
interfere with its operation. A better long-term solution is the SRV
record, which we'll discuss in Chapter 16.
|