CDN — 利用者の近くから配る係

概要 — まず全体をつかむ

初級ではCDNを「近くの倉庫」と捉えました。中級では、鮮度管理(TTL)とキャッシュ制御を見ます。

詳細 — 1段階ずつ追う

これは何をする係?

CDNは、地理的に分散したエッジ拠点(PoP) のキャッシュ網です。要点は「何をキーに、いつまで、どう更新するか」。

  • キャッシュキー — URLなどを鍵に、コピーを出し入れする
  • TTL(有効期限) — その期間はエッジのコピーを新鮮とみなす
  • オリジン — 大元。miss時やTTL切れ時に取りに行く先
アニメーション『CDNのエッジ配信』を開く
オリジン(大元)世界に1つ・全部の元無ければオリジンへ取りに行く(miss)エッジ拠点アジアコピー有 hit利用者最寄りから受け取るエッジ拠点ヨーロッパコピー有 hit利用者最寄りから受け取るエッジ拠点北米コピー有 hit利用者最寄りから受け取るエッジ拠点南米コピー無 miss利用者最寄りから受け取る世界中の拠点に控えを置き、利用者の近くから配る(近い=速い)

登場人物メモ:

  • ※1 cache hit/miss — エッジにある(hit)/無くてオリジンへ(miss)
  • ※2 パージ — エッジのコピーを強制的に無効化する操作
この部分をもっと深く(上級
  • キャッシュキー正規化 — URL・選ばれたクエリ・Vary(言語や圧縮)で「同じ内容は同じキー」に
  • 階層キャッシュ — エッジ → シールド層 → オリジン。オリジンへの問い合わせを束ねる
  • collapse forwarding — 同一キーの同時ミスを1本化してオリジンを守る
やさしく言うと(初級

CDNは、世界中に分散した“利用者の近くの倉庫”(※1 エッジ)の集まり。画像・CSS・JSなど変わらないもののコピーを各地に置き、利用者に一番近い倉庫から配ります。

世界地図上に分散した拠点
CDN — 世界中に散らばる配達拠点

大事なのは「1台の独立したサーバ」ではなく、たくさんの拠点に同じものが並んでいる層だということ。

登場人物メモ:

  • ※1 エッジ — 利用者の近くにある配信拠点。世界中にたくさんある
  • ※2 オリジン — 大元のサーバ(あなたのサービス本体)。エッジに無いときの取り寄せ先

仕事の流れ

  1. リクエストのキャッシュキーで、エッジにコピーがあるか確認
  2. hit かつ TTL 内 ならそのまま返す
  3. miss/TTL切れ ならオリジンへ。条件付きリクエストで「変わってなければそのまま」を確認することも
  4. 取得したものをTTL付きでエッジに保存し、次に備える
アニメーション『エッジ配信の地理(近い=速い)』を開く
エッジ配信の地理 — 近い=速いエッジ拠点アジア利用者最寄りからエッジ拠点ヨーロッパ利用者最寄りからエッジ拠点北米利用者最寄りからエッジ拠点オセアニア利用者最寄りからオリジン(大元)世界に1つ・全部の元各地の拠点に控えを配り、利用者は最寄りエッジから受け取る(距離が短い=速い)
この部分をもっと深く(上級
  1. エッジでキャッシュキーを計算し照合
  2. hit(TTL内)なら即返す。stale-while-revalidate/stale-if-errorで古くても返しつつ更新
  3. miss/期限切れは条件付きリクエスト(ETag・If-None-Match)でオリジンに確認
  4. 変わっていなければ304、変わっていれば新版を取得しTTL付きで保存
やさしく言うと(初級
  1. ブラウザが画像などをお願いする
  2. 一番近いエッジに、そのコピーがあるか見る
  3. あれば即返す(cache hit・速い)
  4. 無ければオリジンから取り寄せて配り、ついでにエッジに保存する(cache miss)
  5. 次からは、その地域の人にはエッジから即返せる

鮮度をどう保つか

  • Cache-Control ヘッダ — キャッシュ可否や期間をオリジンが指示する(max-age など)。private は共有キャッシュ禁止(個人向け応答に付ける)、public は共有可、s-maxage は共有キャッシュ用のTTLを別に指定する
  • ETag/If-None-Match — TTL切れ時、内容の識別子(ETag)を If-None-Match で送って問い合わせ、変わっていなければ 304(Not Modified)で本体を取り直さず、エッジのコピーを使い続ける
  • バージョニング — 内容が変わったらファイル名(URL)を変える。古い版と衝突しない定石
  • パージ/即時無効化 — 緊急時にエッジのコピーを消す
  • 静的と動的 — 変わらないものは長めのTTL、動的なものは短いか非キャッシュ。近年はエッジで軽い処理をする方式もある
この部分をもっと深く(上級
  • エッジコンピュート — エッジで軽い処理(A/B・認証・リライト)を実行し、往復を減らす
  • TLS終端をエッジで — 近い場所で暗号処理、オリジンまで再暗号化も
  • Anycast — 同一IPを各地で広告し、最寄りへ誘導
  • ログ集約と分析 — 多数のエッジのログを集めて可視化
やさしく言うと(初級
  • 速い — 物理的に近い=往復が短い
  • 軽い — 静的なものをエッジが肩代わりし、オリジンの負荷が下がる
  • 強い — アクセスが世界中の拠点に分散するので、一点に集中しない

だから「変わらないもの」はCDN、「その人だけ・刻々と変わるもの」はオリジン、と役割を分けます。

⚠️ うまくいかないとき

  • stale(古いまま) — TTLが長すぎ/パージ漏れで、更新が届かない
  • hit率が低い — キャッシュキーが細かすぎる(クエリ違いで別扱い)などで、ほとんどmiss
  • 個人情報の誤キャッシュ — 個人向けの応答を誤って共有キャッシュに載せてしまう(他人に見える事故。攻撃の「キャッシュ汚染/ポイズニング」とは別物)。防ぐ鍵は Cache-Control: private を付け、共有キャッシュに載せないこと
この部分をもっと深く(上級
  • hit率低下 — キーの細分化、キャッシュ不可ヘッダの付けすぎ
  • 個人情報の誤キャッシュ — Vary設計ミスで個人向けが共有される(別途、攻撃としてのキャッシュ汚染/ポイズニングも存在)
  • パージ遅延 — 全エッジへの無効化が伝わるまでの時間差
  • オリジン過負荷 — シールド/collapseが無いと、ミス時に殺到
やさしく言うと(初級
  • 更新が反映されない — 古いコピーがエッジに残っている(期限切れ or 手動でパージが必要)
  • キャッシュされない — 個人向け・動的なものは基本キャッシュできず、速さの恩恵が薄い

理解度チェック

そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。

1. エッジに置いたコピーを「いつまで新鮮とみなすか」を決める仕組みはどれ?

2. 新しいCSSに差し替えたのに古いのが表示される。安全な解決に近いのは?

3. CDNの「エッジ拠点(PoP)」の説明として正しいのは?

4. Cache-Control の private が意味するのは?

5. Cache-Control の s-maxage が指定するのは?

6. TTL切れ時にETagで問い合わせ、内容が変わっていないと確認できたときの動きは?

7. エッジのコピーを緊急時に強制的に無効化する操作を何という(カタカナまたは英語)?

8. TTL切れ時、内容の識別子(ETag)を送って「変わっていないか」を確認するために使うリクエストヘッダを英字で答えてください。