キャッシュと TTL — 速さと鮮度のトレードオフ
TTL の残り秒数、cache miss の回数、negative caching を秒単位で手計算できるようにする。
TTL は「この答えを何秒信じてよいか」
第 3 章で、キャッシュヒットすれば外向き問い合わせが 0 回になることを見ました。では、キャッシュはいつまで使ってよいのでしょうか。その期限を決めるのが TTL(Time To Live)— すべての DNS レコードに付いている、秒単位の寿命です。
再帰リゾルバは、取得したレコードを TTL が切れるまで再利用します。TTL が長いほど速く、権威サーバの負荷も減ります。その代わり、権威側で値を変えてもすでに配られたキャッシュが尽きるまで古い答えが見え続けます。この章で必要な式は、実は 1 本だけです。
expires_at = fetched_at + TTL — 取得時刻に TTL を足せば、そのキャッシュの死亡時刻が決まります。以降の計算はすべてこの式から派生します。remaining = expires_at - now — 0 になったら再利用できず、次の問い合わせは miss になります。remaining がそのまま「最悪ケースで旧値が見え続ける時間」です。更新操作ではキャッシュを消せません。小問 5-1 — まずは秒数を手で数える
TTL を「なんとなく長い・短い」ではなく、失効時刻の計算として扱います。
Q23. 再帰リゾルバが 12:00:00 に TTL 300 秒のレコードを取得しました。12:03:20 時点の残り TTL は何秒ですか。
失効時刻は 12:00:00 + 300 秒 = 12:05:00。12:03:20 からの残りは 100 秒です。expires_at を先に出してから引き算する、という手順を身につけてください。
Q24. 再帰リゾルバが 12:00:00 に TTL 300 秒の旧レコードを取得しました。権威側は 12:02:00 に新しい値へ更新されました。この再帰リゾルバでは、更新時点から最大あと何秒、旧レコードが返りえますか。
キャッシュの失効時刻は 12:05:00 で、権威側をいつ更新したかはこれに影響しません。12:02:00 から見て最大 180 秒、旧値が生き残ります。「権威を直しても、配られたキャッシュは戻せない」— 切り替え作業で最重要の感覚です。
スライダで体感する
次のシミュレータでは、1 時間のあいだに権威データが何回か更新される状況を作っています。TTL・更新間隔・問い合わせ間隔を動かして、ヒット率と古い答えが返る区間が同時にどう動くかを見てください。片方だけ良くなる設定が存在しないこと — それがこの章の主題です。
小問 5-2 — miss の回数とトレードオフ
TTL を短くすると何が増え、何が減るのか。数字で確かめます。
Q25. 1 つの再帰リゾルバに、0 秒以上 300 秒未満のあいだ 10 秒おきに同じ名前・型の問い合わせが来ます。TTL は 60 秒、最初はキャッシュが空です。権威サーバへの miss は何回起きますか。
初回取得のあと 60 秒ごとに失効するので、miss は 0, 60, 120, 180, 240 秒の 5 回です。同じ設定でも TTL を 300 秒にすれば miss は 1 回になります。
Q26. TTL を短くしたときに起こりやすい変化として正しいものはどれですか。
TTL は速さ(ヒット率・権威側の負荷軽減)と鮮度(変更の見えやすさ)のトレードオフを決めるつまみです。どちらか一方だけ良くする設定はありません。だからこそ「普段は長め、変更前だけ短く」という運用が定石になります。
negative caching — 「なかった」も覚えられている
DNS がキャッシュするのは、存在するレコードだけではありません。「その名前はなかった」(NXDOMAIN)や「その型のデータはなかった」(NODATA)という否定応答も、一定時間キャッシュされます。これを negative caching と呼びます(RFC 2308)。
これを知らないと、次の体験に説明がつきません — 新しいレコードを作る前に誰かがその名前を引いてしまうと、「存在しない」という結果がキャッシュされ、作成後もしばらく「ない」と言われ続けるのです。作業直後の動作確認でハマる典型パターンです。
では、否定応答は何秒キャッシュされるのか。その上限を決めるのが、第 4 章で登場した SOA レコードの minimum フィールドです。SOA の構造をここで通しで見ておきます。
| フィールド | 意味 |
|---|---|
| MNAME | プライマリ権威サーバのホスト名 |
| RNAME | ゾーン管理者のメールアドレス(@ を . に置き換えた表記) |
| serial | ゾーンの版番号。増えるとセカンダリがゾーン転送を取り直す |
| refresh | セカンダリが SOA を確認しに行く間隔(秒) |
| retry | refresh に失敗したときの再試行間隔(秒) |
| expire | プライマリと連絡が取れないままゾーンデータを配り続けてよい猶予(秒) |
| minimum | negative caching TTL の上限(秒)。NXDOMAIN / NODATA はこの時間まで記憶される |
つまり「typo した名前の NXDOMAIN がいつまで残るか」は、その名前を管轄する権威ゾーンの SOA minimum(と応答の TTL)で決まります。どのゾーンの SOA かは否定応答の AUTHORITY セクションに載るので、迷ったら応答を見るのが確実です — 委任された子ゾーン配下の名前なら、親ではなく子ゾーンの SOA が使われます。
小問 5-3 — 否定応答のキャッシュ
「作ったばかりのレコードが見えない」の正体を、秒数で説明できるようにします。
Q27. negative caching の説明として最も正しいものはどれですか。
存在しない名前への問い合わせが繰り返し権威サーバまで届くと無駄なので、DNS は「なかった」という結果もキャッシュします。便利な反面、「いま作ったレコードがまだ見えない」という体験の原因にもなります。
Q28. ある再帰リゾルバが 13:00:00 に NXDOMAIN 応答を 120 秒でキャッシュしました。13:01:00 にその名前のレコードが権威側で新規作成されたとして、その時点からあと何秒待てば、この再帰リゾルバが上流へ問い合わせ直せる状態になりますか。
NXDOMAIN キャッシュの失効時刻は 13:02:00。13:01:00 から見て残り 60 秒です。計算の型は通常のキャッシュとまったく同じで、expires_at = fetched_at + TTL が否定応答にも適用されます。
実務: サーバ切り替えは TTL から逆算する
この章の内容をそのまま運用手順に落とすと、サーバ移転の定石ができあがります。TTL 3600 秒(1 時間)のレコードを切り替える例で見てみます。
- 切り替えの十分前(旧 TTL の 1 周期以上前)に、TTL を 300 秒などへ下げる。ここで焦ってはいけない点がひとつ — TTL を下げる変更自体も、すでに配られた TTL 3600 のキャッシュが切れるまで行き渡りません。だから直前ではなく前日に下げます。
- 切り替え当日、値(IP など)を変更する。この時点で世界中のキャッシュは最長でも 300 秒で失効するので、旧値が見える時間は最大 5 分に抑えられます。
- 安定を確認したら、TTL を元の長さへ戻す。短い TTL のまま放置すると、権威サーバへの問い合わせが増えたままになります。
要点: 変更の反映時間は祈って待つものではなく、expires_at = fetched_at + TTL から事前に計算して設計するものです。
この章で持ち帰ること
- TTL は「この答えを何秒信じてよいか」。すべての計算は
expires_at = fetched_at + TTLに帰着する - TTL は速さと鮮度のトレードオフを決めるつまみ。両方いい設定はない
- 否定応答もキャッシュされる。上限は SOA の minimum。切り替え作業は TTL から逆算して設計する
ここまでの知識を、実際の応答で確かめる道具が必要です。次章では dig を使って、この講座で学んだすべてを目で見ます。