GCP Cloud CDNのキャッシュキーチューニング:エッジのヒット率を極限まで高め、オリジンを守り抜くアーキテクチャ設計
クラウドアーキテクトやSREとして日々大規模なトラフィックと向き合っていると、「Cloud CDNを入れたのに、なぜかオリジンサーバーのCPU負荷が下がらない」「キャッシュヒット率(CHR)が頭打ちになり、グローバルからのリクエストが直接バックエンドを叩いている」という壁にぶつかる。
その原因の多くは、デフォルトのキャッシュキー(Cache Key)戦略にある。HTTP/2やHTTP/3といった最新のトランスポート層の恩恵を受け、TLS終端やヘッダー圧縮(QPACK/HPACK)でどれだけエッジまでのレイテンシを削り込んでも、肝心のキャッシュキーの切り方が甘ければ、エッジサーバー(Google Media CDNのインフラ)は無数のバリエーション違いのコンテンツを「別物」と判断し、泣く泣くオリジンへ往復(Round Trip)することになる。
今回は、GCPのCloud CDNにおけるキャッシュキーのカスタマイズ要素に焦点を当て、パケットレベルの挙動やトランスポートセキュリティ、そして実務で即座に使える具体的な設定手法まで、徹底的に深掘りしていこう。
—
1. キャッシュキーの正体とエッジでのパケット処理メカニズム
そもそも、Cloud CDNにおけるキャッシュキーとは何を指すのだろうか。
ユーザーからのリクエストがグローバルエッジネットワーク(PoP)に到達し、TLSハンドシェイクが完了してHTTPリクエストがパースされた瞬間、Googleのエッジプロキシは「このコンテンツはキャッシュストレージのどこに存在するか」を引くための「キー」を生成する。
デフォルトでは、このキャッシュキーは [HOST] + [PATH] の組み合わせ、つまり URLそのもので構成される。しかし、現代のWebアプリケーションにおいて、URLだけをキーにするのはあまりにもナイーブだ。
クエリパラメータの罠と「順序正規化」の重要性
例えば、マーケティングのトラッキング用パラメータやA/Bテストのフラグが、URLのクエリ文字列としてランダムに付与されてくるとどうなるか。
https://example.com/item?id=100&utm_source=google と https://example.com/item?id=100&utm_source=twitter は、アプリケーションのロジック上は全く同じHTMLやJSONを返すべきであるにもかかわらず、デフォルト設定では別々のキャッシュエントリとしてメモリ上に保持されてしまう。これがキャッシュヒット率を急降下させる主犯格だ。
Cloud CDNでは、キャッシュキーに含めるクエリパラメータを明示的に「許可(Include)」または「除外(Exclude)」できる。さらに強力なのが、クエリパラメータの順序正規化(Query Parameter Sorting)だ。
?a=1&b=2 と ?b=2&a=1 を同一視するようにエッジ側でキーを整列させることで、クライアント側がどのような順序でクエリを送出しようとも、キャッシュヒットの確率を最大限に高めることができる。
—
2. HTTPヘッダーとCookieの制御:Varyヘッダーの呪縛からの解放
動的なWebアプリケーションでは、認証状態(Cookie)やデバイスの種類(User-Agent)、あるいは言語設定(Accept-Language)によってレスポンスを変える必要がある。これらをハンドリングするために、HTTPの Vary ヘッダーが長年使われてきた。
しかし、オリジンサーバーが Vary: User-Agent や Vary: Cookie を返してしまうと、CDNは「すべての異なるUser-AgentやCookieの組み合わせごとに別キャッシュを持たなければならない」と解釈し、キャッシュ効率が実質的にゼロになってしまう(キャッシュポイズニングやキャッシュクラッシュのリスク増大)。
Cloud CDNによるヘッダーとCookieの選択的インクルージョン
Cloud CDNのキャッシュキーカスタマイズ機能を使えば、オリジンの Vary ヘッダーに頼るのではなく、CDNエッジ側で「どのヘッダーとどのCookieをキャッシュキーの構成要素に含めるか」を厳密にコントロールできる。
- HTTPヘッダーの制御: 例えば、レスポンスの圧縮方式(
Accept-Encoding)はトランスポート最適化のために当然含めるべきだが、トラッキング用のカスタムヘッダーなどはキャッシュキーから除外する。 - Cookieの制御: セッション全体をキーにするのではなく、例えば「ログイン済みか否かを示す特定のフラグCookie(例:
is_logged_in=1)」だけを抽出してキャッシュキーに組み込む。これにより、未ログインユーザーの膨大なトラフィックを100%エッジで吸収しつつ、ログインユーザー専用のコンテンツ制御を両立できる。
—
3. 実践:Terraformによる高度なキャッシュキー設定
では、実際にGoogle Cloud上でこのキャッシュキーの最適化をどのように実装するのか。
Infrastructure as Code(IaC)のデファクトであるTerraformを用いて、バックエンドサービス(Backend Service)の設定例を見ていこう。
以下のコードは、クエリパラメータのホワイトリスト方式による制限、特定のCookieの包含、そしてホスト名の大文字小文字の正規化(Canonicalization)を有効にした実用的な設定例である。
resource "google_compute_backend_service" "optimized_backend" {
name = "production-web-backend"
load_balancing_scheme = "EXTERNAL_MANAGED" // EXTERNAL (Classic) ではなく外部アプリケーションLB向けのモダンな構成
protocol = "HTTP2"
enable_cdn = true
# CDNの高度なキャッシュ設定
cdn_config {
cache_mode = "CACHE_STATIC_ALL_CONTENT" // 静的アセット及び動的コンテンツのキャッシュポリシー適用
serve_while_stale = 86400 // オリジン障害時や再検証中に古いキャッシュを返す秒数 (24時間)
negative_caching = true // 404や502などのエラーレスポンスも短期間キャッシュしてオリジンを守る
negative_caching_policy {
code = 404
ttl = 120
}
# キャッシュキーのカスタマイズブロック
cache_key_policy {
include_host = true // ホスト名をキャッシュキーに含める (マルチテナント環境では必須)
include_protocol = false // HTTPとHTTPSを同一視してキャッシュヒット率を上げる場合はfalse (通常はtrue推奨)
include_query_string = true // クエリ文字列をキャッシュキーに含める
# ビジネス上必要なクエリパラメータのみをホワイトリスト指定(順序正規化も自動適用される)
query_string_whitelist = [
"page",
"category_id",
"sort"
]
# ※逆に除外する場合は query_string_blacklist を使用する
# 特定のCookieのみをキャッシュキーに含める(例: 地域設定のCookie)
include_http_cookies = [
"region_locale"
]
# パフォーマンスに直結するAccept-Encodingなどの基本ヘッダー以外は除外
include_http_headers = [
"Accept-Language"
]
}
}
backend {
group = google_compute_instance_group_manager.web_igm.instance_group
balancing_mode = "UTILIZATION"
capacity_scaler = 1.0
}
}
この設定において特筆すべきは、query_string_whitelist の存在だ。これにより、Googleアナリティクス等の utm_* パラメータや、広告効果測定用の gclid がURLに付与されていても、キャッシュキー生成時には綺麗に無視され、オリジンへの無駄なリクエストの奔流を防ぐことができる。
—
4. ネットワーク層・セキュリティ層から見た最適化の勘所
キャッシュキーのチューニングを極めることは、単なるインフラコストの削減(オリジン帯域の節約)にとどまらず、セキュリティとネットワークパフォーマンスの向上に直結する。
TLSハンドシェイクとセッション再開(Session Resumption)の最大化
Cloud CDNのエッジ(Googleフロントエンド / GFE)でリクエストがキャッシュヒットすれば、オリジンサーバーとの間でTCPコネクションを張る必要すらなくなる。
さらに言えば、クライアントとGFE間で行われるTLS 1.3のハンドシェイクや、0-RTT(Zero Round Trip Time)Resumptionの恩恵を、バックエンドをバイパスして最前線で完結させることが可能になる。オリジン側の負荷が下がることで、TLS証明書の検証や暗号化処理に割いていたCPUリソースが解放され、システム全体の耐障害性が飛躍的に向上する。
キャッシュポイズニング脆弱性の回避
もし、キャッシュキーの設計を誤り、悪意のある攻撃者が改ざんしたHTTPヘッダーや未知のクエリパラメータをキャッシュキーに紛れ込ませることができた場合、他の正当なユーザーに対しても汚染されたキャッシュ(不正なコンテンツや機密情報)が返される「キャッシュポイズニング」の踏み台にされてしまう。
これを防ぐためには、以下の鉄則を遵守する必要がある。
1. 不要なヘッダー・Cookieは一切キャッシュキーに入れない: ホワイトリスト方式を徹底し、アプリケーションが実際に処理するもの以外をキーに含めない。
2. CDNレイヤーでの不正文字サニタイジング: GCPのCloud CDNは不正なリクエストやコントロール文字を自動的に弾くが、アプリケーション側でもVaryやキャッシュ制御ヘッダーの意図しない挙動に注意を払う必要がある。
—
5. まとめ
Cloud CDNのキャッシュキーチューニングは、地味ながらインフラストラクチャの成否を分ける極めて重要なエンジニアリング領域である。
デフォルト設定のまま運用を続けることは、高速道路の料金所で全ての車の車検証を一枚一枚目視で確認しているようなものであり、せっかくのグローバルエッジネットワークのポテンシャルをドブに捨てているに等しい。
今回解説したクエリパラメータのホワイトリスト化、順序正規化、そして不要なCookieやヘッダーの排除を適切に行うことで、キャッシュヒット率は劇的に跳ね上がり、オリジンサーバーのネットワークI/OとCPU負荷は美しく平穏を取り戻すだろう。
パケットの流れる経路を想像し、エッジとオリジンの役割分担を正しくデザインする——これこそが、現代のSREおよびクラウドアーキテクトに求められる真のネットワークスキルなのだ。
コメント