【実務・中級編】 GCP Cloud CDNのキャッシュ有効化とエッジサーバーの仕組み – クラウドインフラと仮想化ネットワーク実践ガイド

Google Cloud CDNの「裏側」を理解する:エッジでパケットを止める技術と実務的Tips

こんにちは。SREの現場にいると、「とりあえずCDNを有効化しておけば速くなる」という幻想に直面することがよくあります。しかし、Cloud CDNを真に使いこなすためには、Googleの巨大なグローバルネットワークがパケットをどう扱い、どこでキャッシュを判断しているのか、その「物理的な距離感」と「HTTP仕様」の交差点を知る必要があります。

今日は、教科書には載っていない「現場の肌感覚」を交えつつ、Cloud CDNの深淵に迫っていきましょう。

Cloud CDNが提供する「物理」の恩恵

まず前提として、GCPのCloud CDNは単なる「プロキシの束」ではありません。これはGoogleの持つ広大なエッジネットワーク(GFE: Google Front End)上に展開されたキャッシュ層です。

ユーザーがURLを叩いた瞬間、パケットはインターネットの荒波を越え、最も近いGoogleのPoP(Point of Presence)に到達します。ここで重要なのは、「ロードバランサー(HTTP(S) LB)がキャッシュの判断を下す」という点です。つまり、CDNを有効にするということは、バックエンド(GCEやGKE)の手前に、Googleの超高速なキャッシュ層を「串」として刺す作業に他なりません。

キャッシュヒットの仕組み:シーケンスのリアル

キャッシュが効くか効かないかは、すべて Cache-Control ヘッダーとの対話で決まります。ここで、キャッシュがどのように判断されるかのフローを頭に入れておきましょう。

1. Request: クライアントからリクエストが来る。
2. Edge Cache Check: GFEがリクエストURLをキーとしてキャッシュを検索する。
3. Hit: キャッシュがあれば、バックエンドを介さず即座にレスポンスを返す(X-Cache: HIT)。
4. Miss: キャッシュがなければ、バックエンドへリクエストを転送(オリジンフェッチ)。
5. Storage: バックエンドからのレスポンスをキャッシュし、クライアントへ返す。

この時、もしバックエンドのレスポンスに Cache-Control: public, max-age=3600 のようなヘッダーが含まれていなければ、Cloud CDNは「これはキャッシュしてはいけないものだ」と判断し、毎度バックエンドへパケットを投げ続けます。これが「CDNを入れたのに遅い」というトラブルの典型的な原因です。

実践:キャッシュの挙動をCLIで覗き見る

では、実際に今の構成が正しくキャッシュされているかを確認しましょう。curl を使って、HTTPレスポンスヘッダーを観察するのが一番の近道です。

# -I オプションでヘッダーのみを取得
# 最初のアクセスでキャッシュを温める
curl -I https://your-app.example.com/api/static/data.json

# 2回目にアクセスして X-Cache を確認する
curl -I https://your-app.example.com/api/static/data.json

このとき、レスポンスヘッダーに以下の項目があるかチェックしてください。

  • X-Cache: HIT:キャッシュ成功。エッジでパケットが止まっています。
  • Age: 120:そのキャッシュがエッジに存在してからの秒数。
  • Via: 1.1 google:Googleのインフラを通った証拠。

Pythonによる検証スクリプト

API設計において、意図した通りのキャッシュ制御ができているかテストするためのスクリプト例です。

import requests

url = "https://your-app.example.com/api/v1/resource"

# キャッシュの挙動を確認するヘルパー
def check_cache_status(url):
    response = requests.get(url)
    x_cache = response.headers.get('X-Cache', 'MISS')
    print(f"URL: {url}")
    print(f"Status: {response.status_code}")
    print(f"X-Cache Status: {x_cache}")
    # Ageヘッダーがあれば表示(キャッシュがどれくらい古いか)
    print(f"Age: {response.headers.get('Age', 'N/A')}")

check_cache_status(url)

現場でハマる「キャッシュ無効化」の罠

運用中、最も頭を悩ませるのが「キャッシュのパージ(無効化)」です。デプロイ直後に古いJSファイルが残っている、あるいはAPIのレスポンスが変わったのに古いデータが返る…といった事象は、キャッシュ戦略の不備です。

Google Cloudでは gcloud コマンドでキャッシュの無効化(Invalidation)が行えます。

# 特定のパス以下のキャッシュをすべて無効化する
gcloud compute url-maps invalidate-cdn-cache [ロードバランサー名] \
    --path "/api/v1/static/*" \
    --global

ただし、パージはあくまで「最終手段」です。本質的な解決策は、Cache-Control を適切に設計することにあります。

推奨されるキャッシュ戦略のTips

  • 静的コンテンツ: Cache-Control: public, max-age=31536000(1年)を指定し、ファイル名にハッシュ値を付与してデプロイごとにURLを変える「フィンガープリント方式」を採用する。
  • 動的API: Cache-Control: no-cache を基本とし、CDN側でのキャッシュを無効化する。どうしてもCDNを使いたい場合は、s-maxage を利用してエッジの生存期間だけを制御する。

まとめ:ネットワークのプロとして

Cloud CDNを導入するということは、単にサーバー負荷を減らすことではありません。「Googleの巨大なエッジネットワーク上に、自社のビジネスロジックの一部を分散配置する」という高度な分散コンピューティングを行うことです。

パケットがどのルートを通り、どのヘッダーを見てキャッシュが判断されたのかを論理的に追えるようになれば、CDNは最強の武器になります。まずは、今動いているAPIの X-Cache ヘッダーを確認することから始めてみてください。そこには、Googleのネットワークが皆さんのサービスをどう扱っているかという「事実」が刻まれています。

それでは、良いSREライフを!

コメント

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