CDNキャッシュとTTL最適化
概要
CDNキャッシュは、ユーザーとオリジンの間の「アクセラレータ+シールド」です。それはうまく機能するとき:1.キャッシュキーは安定しており「、ノイズ」は含まれていません。
2.ロード中のTTLポリシー:'s-maxage'/'max-age'+'stale-while-escalate/if-error'。
3.障害は管理されています:タグ/接頭辞+「ソフト」パージ。
4.Tiered-cache/origin-shieldとnegative-cacheが含まれています。
5.レイヤーによるヒット率、p95 TTFB、リターンシェア304という観測性があります。
ベースヘッダーとその意味
'キャッシュコントロール':- 'max-age=
'-ブラウザのTTL。 - 's-maxage=
'-CDN/プロキシのTTL ('max-age'と重なります)。 - 'stale-while-revalidate=
'-古いものを並列に更新します。 - 'stale-if-error=
'-原点エラーが発生したときに古いものを返します。 - 'immutable'-リソースは変更されません(バージョン管理されたアセットに適しています)。
- 'ETag'/'Last-Modified'-304の条件、バイト/CPUの起源を保存します。
- 'Vary'-キャッシュキーに影響を与えるヘッダーのリスト(制限付きで使用!)。
- 'Surrogate-Control'-「拡張」CDNのキャッシュコントロール(サポートされている場合)。
- 'Expires'-時代遅れですが、それでも顧客によって説明されています。
Cache-Control: public, max-age=31536000, immutable
例(安全な陳腐化を伴うセミスピーカー):
Cache-Control: public, s-maxage=300, max-age=60, stale-while-revalidate=600, stale-if-error=86400
ETag: "a1c3..."
キャッシュキーの設計と正規化
目的は、基本的に同じ要求が同じオブジェクトに落ちることです。
URL正規化:ケース、ダブルスラッシュ、トレイルスラッシュ、クエリパラメータの順序。
「noise」: 'utm _'、' fbclid'、'gclid'、任意のrefタグを無視します。
Limited Vary:本当に重要なタイトルのみ("Accept-Encoding"、時には"Accept'、" Accept-Language")。
デバイスクラス:必要に応じて、2-3クラス(モバイル/デスクトップ/タブレット)、無限のユーザーエージェントのブランチを使用します。
Authコンテキスト:デフォルトでプライベートをキャッシュしないでください。signed-URLs/cookies-bypassを使用するか、パブリック/プライベートパスを分離します。
Surrogate-Key: product:123 catalog
Cache-Control: public, s-maxage=300, stale-while-revalidate=600
Vary: Accept-Encoding
コンテンツタイプ別のTTL戦略
障害者ポリシー
URL/プレフィックス: 「/static/2025-11-05/」の下にあるすべてをスイープします。
タグ/キーで:"すべての'カタログ'と'product: 123'を削除します。
ソフトパージ:古いものとしてマークし、オブジェクトを消去しないでください。
イベント駆動:CI/CDまたはadminイベントはwebhookを"invalidate tags'呼び出します。
Recommendation:両方の戦術を組み合わせる:アセットのバージョン管理パス+コンテンツ/ページのtag-purge。
Tiered-cache、 origin-shieldのprewarm
階層キャッシュ:CDNリージョンレイヤー→オリジンリクエストの数が少なくなります。
Origin-shield: 1つの"shield' POP to origin-局所性とヒット率を向上させます。
Prewarm (pre-fetch):イベント/リリース前にホットURL/キャッシュをウォームアップします。
ネガティブキャッシュ:レトラの嵐で起源を圧倒しないように、短時間(30-120秒)キャッシュを5xx/Timeoutします。
APIキャッシュ: いつできるか
GET/HEADとidempotentのみ。
キー:path+essentialクエリ(例えば、'?category=……&page=……')。
検証:'ETag'/'Last-Modified'および's-maxage'。
ユーザーごとのフィルタ:クライアント/エッジ関数にパーソナライゼーションをもたらすか、signed-requests+「public」レスポンスを使用します。
Cache-Control: public, s-maxage=30, max-age=5, stale-while-revalidate=120, stale-if-error=600
ETag: "feed-v42"
キャッシュ中毒対策
ハードURL/ヘッダー正規化;キーのパラメータのホワイトリスト。
疑わしいヘッダー/重複をクリッピングする('X-Forwarded-'、拡張'Accept')。
'Vary'を制限し、ヘッダのサイズ/数を制御します。
ドメイン区切り:private/admin-キャッシュなしの別名で。
レスポンスの検証:4xxをキャッシュしないでください(静的な場合は404を除く)。明示的なポリシーなしで「ユーザー」ページをキャッシュしないでください。
圧縮とフォーマット
テキストのためのBrotli (js/css/json)、 gzip-フォールバック;あらかじめ圧縮された資産は許容されます。
イメージ:サポートがあるwebp/avif;'Vary: Accept'+デリバティブを使用します。
ビデオ/オーディオの範囲要求:CDNはチャンクをキャッシュします。
コンテンツネゴシエーション:キーカーディナリティを低く保ちます(生のUAの代わりにデバイスクラス)。
観測可能性とSLO
主な指標
ヒット比(バイト/リクエストによる)エッジ/階層/シールド。
p50/95/99 TTFB by region and type (static/API)。
Fill-rate/Originの出力-原点にどのくらい行くか。
304率および平均応答のサイズ。
エラー予算:'stale-if-error'/'SWR'問題の共有;パージ周波数。
SLOの例
'p95 TTFB' statics ≤ 120-150 ms、 API GETキャッシュ≤ 200-250 ms。
エッジヒット比≥ 90%、セミスピーカー≥ 60%。
エラー≤ 0の古いブランチからの応答の割合。30日の5%。
設定チートシート
Nginx (CDNまたは自己PoPの前の逆プロキシ)
nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CDN:512m max_size=100g inactive=7d;
map $args $clean_args {
"~(^ &)(utm_ gclid fbclid) """; # default $ args simplified example;
}
server {
listen 443 ssl http2;
set $cache_key "$scheme$request_method$host$uri?$clean_args $http_accept $http_accept_encoding";
location /static/ {
proxy_cache CDN;
proxy_cache_key $cache_key;
proxy_ignore_headers Set-Cookie;
add_header Cache-Control "public, s-maxage=86400, max-age=3600, stale-while-revalidate=600" always;
proxy_pass https://origin_static;
}
location /api/public/ {
proxy_cache CDN;
proxy_cache_key $cache_key;
proxy_cache_valid 200 30s;
add_header Cache-Control "public, s-maxage=30, max-age=5, stale-while-revalidate=120, stale-if-error=600" always;
proxy_set_header If-None-Match $upstream_http_etag;
proxy_pass https://origin_api;
}
}
Envoy (SWR+negative-cache、コンセプト)
yaml http_filters:
- name: envoy. filters. http. cache typed_config:
"@type": type. googleapis. com/envoy. extensions. filters. http. cache. v3. CacheConfig typed_config:
"@type": type. googleapis. com/envoy. extensions. cache. simple_http_cache. v3. SimpleHttpCacheConfig
Cache-Control/Surrogate-Control Header Cache Policies
We cache 5xx errors briefly via route/retry policy + local_rate_limit
「高速」アセットのヘッダー
Cache-Control: public, max-age=31536000, immutable
ETag: "hash"
Content-Encoding: br
セミスピーカー用ヘッダー(カタログ)
Cache-Control: public, s-maxage=600, max-age=120, stale-while-revalidate=1800, stale-if-error=86400
Vary: Accept-Encoding, Accept
FinOps: 現金がお金を節約する方法
出出口の原点:CPU/DBの負荷が少ない→インフラストラクチャコストが低くなります。
有料バックエンド(search/index/images)へのリクエストが少なくなりました。
ターゲットメトリック:p95の$/減少、および1 GBの出力の$/減少-起動後の効果を追跡します。
iGaming/fintech固有の
プロバイダカタログ/アセット:バージョン管理されたパス+年間TTL。
イベント/トーナメントの着陸:10-30分のための1-5 min 's-maxage'+'SWR';アップグレード時にtag-purge。
Livページ(係数/テーブル):JSONブロックの部分キャッシュ、パーソナルブロックの短いTTL (5-30 s)-クライアントレンダリング。
PSP/決済エンドポイント:キャッシュしない、厳密な'no-store';参照書籍のみをキャッシュします(BINテーブル、ステータス)。
Antibot: 静的/GETキャッシュ、疑わしいASNのための灰色のルート;騒々しい見出しから'Vary'を保って下さい。
実装チェックリスト
- キャッシュキーの説明:URL正規化、許可されているクエリのリスト、必要なクエリのみ'Vary'。
- パブリック/プライベートパスが分離されました。private-'no-store'とバイパスCDN。
- 導入されたコンテンツタイプによるTTLはしご;'SWR/if-error'を設定しました。
- tiered-cache+origin-shield構成;negative-cache 5xx (short)を有効にしました。
- タグ/URLパージ、ソフトパージがあります。CI/CDとの統合。
- 圧縮(br/gzip)、 Web画像フォーマット、および範囲応答が含まれます。
- メトリクス:レイヤー別ヒット比、p95 TTFB、 304レート、オリジンエグレス;失敗への警告。
- プレイブック:ピーク前のウォームアップ、緊急パージ、起源の劣化をキャッシュします。
よくあるエラー
ユーザーからの大きなTTL→「sticky」バンドルを持つ非バージョンアセット。
過度の'Vary' ('User-Agent'による、すべてのヘッダー)→カルディナリティの爆発と低いヒット率。
4xx/401/403/プライベートコンテンツをキャッシュします。
negative-cacheの欠如→劣化した起源の要求の雪崩。
タグパージ→大規模なポイントパージと嵐の再充填はありません。
キャッシュキーには「noisy」 UTM/refパラメータが含まれています。
statics→CDNおよびoriginの余分負荷のための余りに短いTTL。
ミニプレイブック
1)イベント前にキャッシュをウォームアップする
1.ログでトップNのURLを集める→2)平行プリフェッチ(rate-limited) by region→3) hit-ratioをチェックします。
2)緊急の柔らかいパージのcatologists
1.送信'PURGE '/tag-clear→2) CDNは古くなり、背景で新鮮に引き上げます→3)原点にスパイクがないかチェックします。
3)起源の失敗
1.「stale-if-error」はX時間→2)エッジ上のバナー「技術的作業」を有効にする→3)回復時-ターゲットのウォームアップ。
[結果]
強力なCDN戦略=正しいキャッシュキー+SWR/if-error+管理障害+階層型/シールド+観察可能性を備えた有意義なTTL。ヘッダーとIaCのポリシーを修正し、ヒット率とP95を測定し、ピークまでウォームアップする予定です。ユーザーは常に迅速な回答を受け取り、最も暑い時間でも原点は生き残ります。