【実務・中級編】 GCP Cloud CDNのキャッシュキー(Cache Key)の構成要素とカスタマイズ仕様 – クラウドインフラと仮想化ネットワーク実践ガイド

GCP Cloud CDNの「キャッシュキー」を制する者は、Webパフォーマンスを制する。

現場でSREをしていると、「CDNを導入したのにキャッシュヒット率が上がらない」「特定のユーザーだけ古いコンテンツが見えている」という相談をよく受けます。その原因のほとんどは、キャッシュキー(Cache Key)の設計ミスです。

Cloud CDNは単なる「リクエストをキャッシュする箱」ではありません。リクエストのどの要素を「識別子」として採用するかを正しく制御できていないと、キャッシュの効率はガタ落ちし、オリジンサーバーへ無駄なトラフィックが流れ込みます。

今回は、Cloud CDNのキャッシュキーの仕組みと、実務でハマりやすいポイントを深く掘り下げて解説します。

—

そもそも「キャッシュキー」とは何か?

キャッシュキーとは、Cloud CDNが「このリクエストは、以前取得したあのレスポンスと同じものか?」を判定するための「指紋」のようなものです。

デフォルトでは、Cloud CDNは以下の要素を組み合わせてこの指紋を生成します。

1. プロトコル: http か https か。
2. ホスト名: リクエスト先のドメイン。
3. パス: /api/v1/resource のようなパス部分。

しかし、現代のAPI設計ではこれだけでは不十分です。クエリパラメータや特定のHTTPヘッダーがレスポンスの内容を左右することが多いため、これらをキャッシュキーに含める(あるいは除外する)カスタマイズが必要になります。

—

キャッシュキーのカスタマイズ:4つの主要構成要素

GCPでは、Backend Serviceの定義において、CacheKeyPolicyを調整することで詳細な制御が可能です。

1. クエリパラメータの制御

最も頻繁に調整するのが queryStringWhitelist(許可リスト)または queryStringBlacklist(拒否リスト)です。例えば、utm_sourceのようなトラッキング用パラメータはキャッシュキーから除外しないと、同じページなのにパラメータが違うだけで別キャッシュ扱いになり、キャッシュヒット率が壊滅します。

2. HTTPヘッダーの取り扱い

includeHttpHeaders を使うことで、特定のヘッダーをキーに含められます。例えば、モバイルとPCでレスポンスを出し分ける場合に User-Agent を含めるといったケースが考えられますが、これは慎重に扱うべきです。 User-Agent は種類が多すぎて「キャッシュの細分化(Cache Fragmentation)」を招き、ヒット率を著しく低下させるからです。

3. プロトコル(HTTP/HTTPS)の含めるべきか?

includeProtocol を有効にすると、同じURLでもプロトコルが違えば別キャッシュになります。基本的には true で運用しますが、HTTPからHTTPSへ強制リダイレクトしている環境であれば、キャッシュ層で分ける必要がないこともあります。

4. ホスト名の分離

includeHost を有効にすると、api.example.com と cdn.example.com でパスが同じでも別々にキャッシュされます。マルチテナント環境では非常に重要です。

—

実践:Terraformでのキャッシュキー最適化設定

現場での運用を考えると、コンソールでのポチポチ設定は推奨しません。Terraformでの定義例を見てみましょう。

resource "google_compute_backend_service" "api_backend" {
  name = "api-backend"
  
  cdn_policy {
    cache_key_policy {
      # 1. プロトコルはキャッシュキーに含める(推奨)
      include_protocol = true
      # 2. ホスト名は含める(マルチドメイン対応)
      include_host     = true
      # 3. クエリパラメータは「必要なものだけ」をホワイトリスト化する
      # これにより、不要なパラメータ(utm_系など)によるキャッシュ汚染を防ぐ
      query_string_whitelist = ["id", "version", "region"]
      
      # 4. 特定のカスタムヘッダーをキーに含める例
      # APIのバージョン制御をヘッダーで行っている場合
      include_http_headers = ["X-API-Version"]
    }
  }
}

—

トラブルシューティング:キャッシュが効かない時のデバッグ手順

キャッシュキーの設計が正しいか確認するには、実際にレスポンスヘッダーを覗くのが一番の近道です。curlコマンドを使って、CDNからのレスポンスを確認しましょう。

# -I でヘッダーのみを取得
# -H で必要に応じて検証用ヘッダーを追加
curl -I -H "X-API-Version: v1" "https://api.example.com/data?id=123&utm_source=google"

この際、注目すべきは以下のヘッダーです。

  • Via: 1.1 google とあればCloud CDNを通過しています。
  • Age: キャッシュに滞在している秒数。0の場合はミスです。
  • X-Cache: HIT か MISS か。MISS が続く場合は、キャッシュキーがリクエストごとに変わっていないか疑ってください。

SREの教訓:パラメータの順序に注意

意外と見落としがちなのが、クエリパラメータの順序です。
Cloud CDNの queryStringWhitelist は、パラメータをキーに含める際、通常は「指定されたパラメータのみ」を識別子として使います。しかし、パラメータの「順序」がバラバラ(?a=1&b=2 と ?b=2&a=1)の場合、CDNの設定によっては別キャッシュとして認識されることがあります。

これを防ぐには、アプリケーション側でURL生成時にパラメータを辞書順にソートしておくのが、現場レベルでのベストプラクティスです。

—

まとめ:設計の哲学

キャッシュキーの設定において最も重要なのは、「何を変数として扱うか」というビジネスロジックの理解です。

  • ヒット率を稼ぎたいなら: キーを可能な限り抽象化(固定化)する。
  • 正確性を担保したいなら: キーに情報を詰め込む。

このトレードオフを理解し、Terraform等のコードで構成管理を行うことが、大規模Webサービスを運用するSREの第一歩です。次のデプロイでは、一度 CacheKeyPolicy を見直してみてはいかがでしょうか。きっと、オリジンサーバーのCPU負荷が劇的に下がるはずです。

コメント

タイトルとURLをコピーしました