8.4 Changing TTLs
An
experienced administrator needs to know
how to set the time to live on his zone's data to his best
advantage. The TTL on a resource record,
remember, is the length of time any name server can cache that
record. So if the TTL for a particular resource record is 3600
seconds and a server outside your network caches that record, it has
to remove the entry from its cache after an hour. If it needs the
same data after the hour is up, it has to query one of your name
servers again.
When we introduced TTLs, we emphasized that your choice of a TTL
dictates how current you keep copies of your data at the cost of
increased load on your name servers. A low TTL means that name
servers outside your network have to get data from your name servers
often and therefore keep current. However, your name servers are then
peppered by their queries.
You don't have to choose a TTL once and
for all, though. You can—and experienced administrators
do—change TTLs periodically to suit your needs.
Suppose we know that one of our hosts is about to be moved to another
network. This host houses the movie.edu film library, a large
collection of files our site makes available to Internet users.
During normal operation, outside name servers cache the address of
our host according to the default TTL set in the $TTL control
statement, or for pre-BIND 8.2 name servers, in the SOA record. We
set the default TTL for movie.eduto three hours in our sample files. A name server
caching the old address record just before the change could have the
wrong address for as long as three hours. A loss of connectivity for
three hours is unacceptable, though. What can we do to minimize the
loss of connectivity? We can lower the TTL so that outside servers
cache the address record for a shorter period. By reducing the TTL,
we force the outside servers to update their data more frequently,
which means that any changes we make when we actually move the system
are propagated to the outside world quickly. How long can we make the
TTL? Unfortunately, we can't safely use a TTL of zero, which
should mean "don't cache this record at all." Some
older BIND 4 name servers can't return records with a TTL of
zero, instead returning null answers or SERVFAIL errors. Small TTLs,
like 30 seconds, are okay, though. The easiest change is to lower the
TTL in the $TTL control statement in the db.movie.edu
file. If you don't place an explicit TTL on resource
records in the zone data files, the name server applies this
default TTL
to
each resource record. If you lower the default TTL, though, the new,
lower default applies to all zone data, not just the address of the
host being moved. The drawback to this approach is that your name
server will be answering a lot more queries since the querying
servers will cache all the data in your zone for
a shorter period. A better alternative is to put a different TTL only
on the affected address record.
To add an explicit TTL on an individual resource record, place it before the IN in
the class field. The TTL value is in seconds by default, but you can
also specify units of m (minutes),
h (hours), d (days), and
w (weeks), just as you could in the $TTL control
statement. Here's an example of an explicit TTL from
db.movie.edu:
cujo 1h IN A 192.253.253.5 ; explicit TTL of 1 hour
If you're observant and have read RFC 1034, you may have
noticed a potential problem when loading this record on an older name
server: the explicit TTL on cujo's address is one hour, but
the TTL field in the SOA
record—ostensibly the minimum TTL for the zone on pre-BIND 8.2
name servers—is higher. Which takes precedence?
If older BINDs followed the original DNS RFCs to the letter, the TTL
field in the SOA record would really define the minimum TTL for all
resource records in the zone. Thus, you could specify only explicit
TTLs larger than this minimum. Older BIND name servers don't
work this way, though. In other words, in BIND, "minimum"
is not really minimum. Instead, BIND interprets the minimum TTL field
in the SOA record as a "default" TTL. (Newer BINDs, of
course, have the explicit default TTL set with $TTL to go by.) If
there is no TTL on a record, the minimum applies. If there is a TTL
on the resource record, BIND allows it even if it is smaller than the
minimum. That one record is sent out in responses with the smaller
TTL, while all other records are sent out with the
"minimum" TTL from the SOA record.
You should also know that when giving out answers, a slave supplies
the same TTL a primary master does—that is, if a primary gives
out a TTL of one hour for a particular record, a slave will, too. The
slave doesn't decrement the TTL according to how long
it's been since it loaded the zone. So, if the TTL of a single
resource record is set smaller than the default, both the primary and
slave name servers give out the resource record with the same,
smaller TTL. If the slave name server has reached the expiration time
for the zone, it expires the whole zone. It will never expire an
individual resource record within a zone.
So BIND does allow you to put a small TTL on an individual resource
record if you know that the data is going to change shortly. Thus,
any name server caching that data caches it only for a brief time.
Unfortunately, while BIND makes tagging records with a small TTL
possible, most administrators don't spend the time to do it.
When a host's address changes, you often lose connectivity to
it for a while.
More often than not, the host having its address changed is not one
of the main hubs on the site, so the outage affects few people. If
one of the mail hubs or a major web server or FTParchive—like the film library—is moving,
though, a day's loss of connectivity may be unacceptable. In
cases like this, the administrator should plan ahead and reduce the
TTL on the data to be changed.
Remember that the TTL on the affected data needs to be lowered
before the change takes place. Reducing the TTL
on a workstation's address record and changing the
workstation's address simultaneously may do you little or no
good; the address record may have been cached seconds before you made
the change and linger until the old TTL times out. And
be sure to factor in the time it'll take your slaves
to load from your primary master. For example, if your default TTL is
12 hours and your refresh interval is 3 hours, be sure to lower the
TTLs at least 15 hours ahead of time, so that by the time you move
the host, all the old, longer-TTL records will have timed out. Of
course, if all your slaves are BIND 8 or 9 name servers that use
NOTIFY, the slaves shouldn't take the full refresh interval to
synch up.
8.4.1 Changing Other SOA Values
We briefly mentioned increasing the refresh interval as a way of
offloading your primary master name server. Let's discuss
refresh in a little more detail and go over the remaining
SOA values, too.
The refresh value,
you'll remember, controls how often a slave checks whether its
zone data is up to date. The retry value then
becomes the refresh time after the first failure to reach a master
name server. The expire value
determines how long zone data can be held before it's
discarded, when a master is unreachable. Finally, on pre-BIND 8.2
name servers, the default
TTL sets how long zone information may be cached. On
newer name servers, the last SOA field is the negative caching TTL.
Suppose we've decided we want the slaves to pick up new
information every hour instead of every three hours. We change the
refresh value to 1h in each of the zone data
files (or with the -o option to
h2n). Since retry is related to refresh, we
should probably reduce retry, too—to every 15 minutes or so.
Typically, retry is less than refresh, but that's not
required. Although lowering the refresh value will speed up the
distribution of zone data, it will also increase the load on the name
server being loaded from, since the slaves will check more often. The
added load isn't much, though; each slave makes a single SOA
query during each zone's refresh interval to check its
master's copy of the zone. So with two slave name servers,
changing the refresh time from three hours to one hour will generate
only four more queries (per zone) to the primary master in any
three-hour span.
Of course, if all of your slaves run BIND 8 or 9 and you use NOTIFY,
refresh doesn't mean as much. But if you have even one BIND 4
slave, your zone data may take up to the refresh interval to reach
it.
Some older versions of BIND slaves stopped answering queries during a
zone load. As a result, BIND was modified to spread out the zone
loads, reducing the periods of unavailability. So, even if you set a
low refresh interval, your slaves may not check exactly as often as
you request. BIND 4 name servers attempt a certain number of zone
loads, and then wait 15 minutes before trying another batch. On the
other hand, BIND 4.9 and later may also refresh moreoften than the refresh interval. These newer BINDs wait a
random number of seconds between one-half the refresh interval and
the full refresh interval to check serial numbers.
Expiration times on the order of a week are common—longer if
you frequently have problems reaching your updating source. The
expiration time should always be much larger than the retry and
refresh intervals; if the expire time is smaller than the refresh
interval, your slaves will expire their data before trying to load
new data. BIND 8 will complain if you set an expire time less than
refresh plus retry, less than twice retry, less than seven days, or
greater than six months. (BIND 9.1.0 doesn't complain yet.)
Choosing an expire time that meets all BIND 8's criteria is a
good idea in most situations.
If your zone's data doesn't change much, you might
consider raising its
default
TTL. Default TTLs are commonly a few hours to one day, but you can
use longer values. One week is about the longest value that makes
sense for a TTL. Longer than that and you may find yourself unable to
change bad, cached data in a reasonable amount of time.
|