103. エッジのコンテンツ更新には3つの伝え方がある — 期限で待つ・無効化で消す・名前を変える
CloudFrontのエッジに一度置いたコンテンツを「どうやって新しくするか」——期限で待つ・無効化で消す・名前を変える、という3つの手段がそれぞれ何を犠牲に何を買っているのかを、図で追っていきます。
① 期限切れは「削除」ではなく「再検証の合図」
- "After it expires, the next time the edge location gets a request for the file, CloudFront forwards the request to the origin to verify that the cache contains the latest version of the file."(公式)
- "If the CloudFront cache already has the latest version, the origin returns a status code 304 Not Modified." / "If the CloudFront cache does not have the latest version, the origin returns a status code 200 OK and the latest version of the file."(公式)
- 補足: 人気のないオブジェクトは期限前でもエビクション(追い出し)され得る——"If a file in an edge location isn't frequently requested, CloudFront might evict the file—remove the file before its expiration date"(公式)。前レッスンで見たエビクションの復習。
期限切れ=削除ではなく、次の要求を引き金にした「これ最新ですか?」という再検証の合図。オリジンが304を返せば本体は流れない。304という条件付きリクエストの応答は、可観測性編・API Gateway編で見たHTTPの条件付きリクエストがそのまま実戦投入されたもの。
② TTLはどう決まるか — キャッシュポリシーとオリジンヘッダの合成
- "If you opt out of using a cache policy, the default TTL (Time to Live) is 24 hours"(公式・執筆時に現行ドキュメントで確認: 24時間)。
- "If you specify values both for Cache-Control max-age and for Expires, CloudFront uses only the value of Cache-Control max-age."(公式)
- max-ageあり(Min TTL=0)のとき: "CloudFront caches the object for the lesser of the value of the Cache-Control: max-age directive or the value of the CloudFront maximum TTL."(公式)=ヘッダ値とMax TTLの小さい方。
- s-maxageあり(Min TTL=0)のとき: "CloudFront caches the object for the lesser of the value of the Cache-Control: s-maxage directive or the value of the CloudFront maximum TTL."(公式)。ブラウザはmax-ageの値でキャッシュする。
- Expiresあり(Min TTL=0)のとき: "CloudFront caches the object until the date in the Expires header or for the value of the CloudFront maximum TTL, whichever is sooner."(公式)
TTLは「オリジンのヘッダ ∧ CloudFrontのMax TTLでキャップ」の合成で決まる。s-maxageの存在意義は、1つの応答でブラウザ(max-age)と共有キャッシュ(s-maxage)の寿命を別々に書けること。ヘッダが皆無なら既定24時間に落ちる。
③ ビューワーには強制再取得の権限がない
- "You cannot use the HTTP Cache-Control or Pragma header fields in a GET request from a viewer to force CloudFront to go back to the origin server for the object. CloudFront ignores those header fields in viewer requests."(公式)
強制再取得の権限は利用者側にない。キャッシュの寿命を決めるのはオリジンと配信者であって、閲覧者ではない。だからこそ「エッジに残った古いコピー」を配信者が能動的に消すための手段(=次の④⑤)が必要になる。
④ 古さを許して速度と可用性を買う — stale-while-revalidate / stale-if-error
- stale-while-revalidate: "CloudFront to serve stale content from the cache while CloudFront asynchronously fetches a fresh version from the origin."(公式)例ではmax-age=3600, stale-while-revalidate=600 → 最大10分のstale配信。
- stale-if-error: "allows CloudFront to serve stale content from the cache if the origin is unreachable or returns an error code that is between 500 and 600."(公式)例ではstale-if-error=86400 → 最大24時間のstale配信。
- 両者とも"the value of the … directive or the value of the CloudFront maximum TTL, whichever is less"でMax TTLに頭打ちされる。Max TTLを超えると、値に関わらずstaleは配れなくなる。
stale-while-revalidateは「古さ↔速度」、stale-if-errorは「古さ↔可用性」の交換。stale-if-errorは、DynamoDB編以来くり返してきた「一貫性を落として可用性を買う」トレードオフを、応答ヘッダ1行で明示的にONにするスイッチそのもの。
⑤ 無効化で消す — ただしCloudFrontのキャッシュにしか効かない
- "Invalidate the file from edge caches. The next time a viewer requests the file, CloudFront returns to the origin to fetch the latest version of the file."(公式)
- 効く範囲の限界(公式): "If you invalidate the file, the user might continue to see the old version until it expires from those caches."——locally(ブラウザ)や corporate caching proxy に残った版のこと。
- 課金: "The first 1,000 invalidation paths that you submit per month are free; you pay for each invalidation path over 1,000 in a month."(公式)ワイルドカード(例 /*)を含むパスは、何千ファイルを消しても1パスと数える。
- この無料枠1,000パス/月は、ディストリビューション毎ではなくAWSアカウント単位(全ディストリビューション合算)で数える。
無効化はCloudFrontのエッジキャッシュにしか効かない。ブラウザや企業プロキシに残ったコピーには届かず、そこが古いままになり得る——これが「消す」手段の構造的な弱点。
⑥ 名前を変える — 「更新」を「別オブジェクトの新規作成」に変える
- 公式の推奨: "If you want to update your files frequently, we recommend that you primarily use file versioning"。
- 全キャッシュ層に効く: "Versioning enables you to control which file a request returns even when the user has a version cached either locally or behind a corporate caching proxy."(公式)
- ログ分析: "CloudFront access logs include the names of your files, so versioning makes it easier to analyze the results of file changes."(公式)——無効化ではログでの版の追跡がしにくい。
- ロールバック: "Versioning simplifies rolling forward and back between file revisions."(公式)——無効化で戻すには、再度無効化とオリジン側の差し替えが要る。
- 費用: "Versioning is less expensive. You still have to pay for CloudFront to transfer new versions of your files to edge locations, but you don't have to pay for invalidating files."(公式)——新しい名前の転送費用のみで、無効化の追加費用なし(⑤の1,000パス/月超の課金と対比)。
名前を変えることで、⑤で届かなかったブラウザ・企業プロキシにも「必ず」新版が届く。これはコンテナ編のイミュータブルなイメージ、S3編の「上書きせず別オブジェクト」と同じ思想の合流点——中身を書き換えず、新しい名前の不変オブジェクトを作る。
⑦ 締め — 3つの手段を対価で並べる
- 「キャッシュ無効化(cache invalidation)と命名(naming things)は計算機科学の2大難問」という有名な格言の両方が、この回に登場した。
3手段を対価で並べると——期限で待つ(タダだが遅い)、無効化で消す(速いがCloudFrontにしか効かず有料)、名前を変える(全層に必ず届き安価だが参照の差し替えが要る)。一番堅い答えは「無効化しない」——難問の1つ(無効化)を、もう1つ(命名)を使って回避する、というのがこの回の芯。