【テクニカル・上級編】 Cloud CDNのNegative Caching(ネガティブキャッシュ)の挙動 – クラウドインフラと仮想化ネットワーク実践ガイド

Cloud CDNのNegative Cachingを極める:エラーレスポンスをエッジで封じ込め、オリジンを守り抜くアーキテクチャ

こんにちは。SREとして日々クラウドインフラの荒波と格闘している私ですが、ネットワークスタックの深部、とりわけパケットがグローバルエッジを駆け巡り、カーネルのソケットバッファを通過してアプリケーション層に到達するまでの挙動を想像するだけで、今でもご飯が3杯は食べられます。

今回は、GCPのグローバルネットワークの要である Cloud CDN に焦点を当てます。取り上げるテーマは Negative Caching(ネガティブキャッシュ) です。

「CDNといえば、画像や動画などの静的コンテンツをキャッシュしてオリジンを救うもの」――それは基本中の基本です。しかし、実運用においてオリジンサーバーやバックエンドのマイクロサービス群を本当に苦しめるのは、正常なレスポンスではなく、「存在しないリソースへの大量の 404 Not Found」 や、「上流の障害による 502 Bad Gateway」 といったエラーの嵐ではないでしょうか。

ボットネットによる存在しないURLへの総当たり攻撃や、デプロイ直後のバグに起因するトラフィックのスパイクがオリジンに直撃したとき、バックエンドのDBプールやプロセスは瞬時に枯渇します。この悪夢からオリジンを物理的・論理的に隔離するための切り札が、Cloud CDNのネガティブキャッシュです。

今回は、単なる機能紹介にとどまらず、エッジにおけるパケット処理、TLSハンドシェイクの最適化、HTTP/2・HTTP/3のヘッダー圧縮、そして現場で役立つ具体的な設定手法まで、インフラエンジニアの知的好奇心を刺激する深度で徹底的に解説します。

—

1. ネガティブキャッシュの内部挙動:パケットとエッジメモリの生態系

私たちがブラウザから https://example.com/not-found-path にアクセスした瞬間、TCP/TLSのハンドシェイクから始まる一連のネットワークシーケンスの中で、Cloud CDNのエッジ(GoogleのGlobal External HTTP(S) Load BalancerのPoP)は次のような判断を下しています。

1. リクエストの受信とエッジキャッシュのルックアップ:
エッジサーバーは、クライアントからの GET または HEAD リクエストを受け取ると、URLパスとキャッシュキーに基づいてローカルの高速なメモリ(SSDではなくDRAM層)を検索します。
2. オリジンへのフォワード:
キャッシュミス(あるいはキャッシュ対象外)の場合、Googleのバックボーンネットワークを経由してオリジンサーバーへリクエストが転送されます。
3. エラーレスポンスの捕捉と評価:
オリジンから 404 Not Found や 502 Bad Gateway などのステータスコードが返却された際、Cloud CDNの設定(Negative Cachingが有効かつ対象のステータスコードに合致している場合)において、そのレスポンスは「キャッシュ可能な異常系データ」としてマークされます。
4. TTLに基づくエッジホールド:
指定されたTTL(Time To Live)の間、同じURLに対する後続のリクエストは、オリジンに1バイトも到達することなく、エッジサーバーから即座にクライアントへ折り返されます。

ここで重要なのは、「エッジがオリジンの代わりにエラーを即座に返すことで、TCPのコネクション確立コストとバックエンドの演算コストを完全に肩代わりする」という点です。

—

2. ネットワークとプロトコルの最適化:RTT削減からTLSまで

Cloud CDNを語る上で欠かせないのが、Googleの巨大なエッジネットワークが生み出すトランスポート層の最適化です。ネガティブキャッシュがヒットするシーンにおいても、この恩恵は最大限に発揮されます。

AnycastとTCPラウンドトリップの極小化

Googleの外部ロードバランサーは、クライアントに最も近いエッジPoPでBGP Anycastにより終端されます。ネガティブキャッシュが有効であれば、存在しないリソースへのリクエストは地球の反対側にあるオリジンサーバーまで到達せず、ユーザーの数ミリ秒圏内にあるエッジPoPのカーネルソケットから直接 RST やエラーレスポンスが返されます。これにより、RTT(Round Trip Time)は劇的に短縮されます。

TLS 1.3と0-RTTの活用

セキュアな通信 (HTTPS) が当たり前となった現代において、TLSハンドシェイクのオーバーヘッドは無視できません。Cloud CDNは最新のTLS 1.3をフルサポートしており、ハンドシェイクの往復を1回(1-RTT)に削減しています。さらに、一度接続したクライアントであれば、セッションresumptionや0-RTTデータによって、確立と同時にリクエストを流し込むことが可能です。
エラーレスポンスであっても、この暗号化のオーバーヘッドがエッジで完結するため、オリジンのCPUをTLS終端処理から解放できます。

HTTP/2 および HTTP/3 (QUIC) のヘッダー圧縮と輻輳制御

クライアントとエッジ間の通信には、HPACK(HTTP/2)やQPACK(HTTP/3)といった動的テーブルベースのヘッダー圧縮が適用されます。エラーレスポンスそのものは軽量ですが、大量のボットトラフィックが押し寄せる環境では、パケットヘッダーのオーバーヘッド削減だけでもエッジのNICやCPU負荷に大きく貢献します。
また、UDPベースのHTTP/3(QUIC)を使用することで、パケットロスが発生した際でもヘッド・オブ・ライン・ブロッキング(HoLブロック)が回避され、エラーメッセージが確実かつ迅速にクライアントへデリバリーされます。

—

3. セキュリティと脆弱性回避:DDoSとキャッシュポイズニングの防壁

ネガティブキャッシュは強力な武器ですが、設計を誤るとセキュリティ上のリスクを生む二面性を持っています。プロフェッショナルとして、ここを厳かにスルーするわけにはいきません。

1. HTTP 404 / 502 洪水(DDoS攻撃)に対する盾

悪意ある攻撃者が、存在しない重たいクエリやランダムなパスに対して数百万QPSの GET リクエストを送りつける「ランダムURL攻撃」は、オリジンのデータベース(特にSQLのフルスキャンやインデックス検索を引き起こすケース)を容易にクラッシュさせます。
ネガティブキャッシュを適切に設定していれば、2発目以降のリクエストはエッジで即座に弾かれるため、オリジンは平和を保ちます。

2. キャッシュポイズニングとステータスコードの罠

ここで注意しなければならないのが、「どのエラーコードをどこまでのTTLでキャッシュするか」という設計です。
例えば、アプリケーションの一時的なバグによる 500 Internal Server Error や 502 Bad Gateway を長すぎるTTL(例: 1時間)でネガティブキャッシュしてしまうと、バグが修正されてオリジンが正常化した後も、ユーザーに対してエラー画面が出続け、サイト全体がダウンしているかのような錯覚を与えてしまうという致命的なインシデント(セカンダリ障害)に繋がります。

【設計の鉄則】

  • 4xx系(特に 404 Not Found, 410 Gone): 比較的長めのTTL(数分〜数時間)を許容。URL構造が変わらない限り、存在しないものは存在しないため。
  • 5xx系(502, 503, 504): 極めて短いTTL(数秒〜数テン秒)に絞るか、場合によってはネガティブキャッシュの対象外(またはパージの自動化を前提とする)にする。オリジンの復旧速度を阻害しないことが最優先です。

—

4. 実践:Google Cloud環境におけるNegative Cachingの設定とチューニング

理論はこのあたりにして、実際にGCP環境でCloud CDNのネガティブキャッシュを構成・チューニングする方法を見ていきましょう。

GCPでは、Backend Service(バックエンドサービス)単位でネガティブキャッシュの挙動をきめ細かく制御できます。デフォルトでは一部のステータスコード(404 など)のみが対象ですが、これをカスタムステータスコードと個別のTTLで拡張します。

gcloud CLIを用いた設定例

以下のコマンドは、特定のバックエンドサービスに対して、404(Not Found)、410(Gone)、および一時的な障害を示す 502(Bad Gateway)をネガティブキャッシュの対象とし、それぞれに最適なTTLを割り当てる実例です。

# バックエンドサービスのネガティブキャッシュポリシーを更新する
gcloud compute backend-services update my-web-backend-service \
    --global \
    --enable-negative-caching \
    --negative-caching-policy="404=300,410=3600,502=5" \
    --project=my-production-project

【コード解説】

  • --enable-negative-caching: このバックエンドサービスでネガティブキャッシュ機能を有効化します。
  • --negative-caching-policy: ステータスコードとTTL(秒単位)のマッピングを定義しています。
  • 404=300: 存在しないファイルやページへのアクセスは 300秒(5分間) エッジでキャッシュし、オリジンを守ります。
  • 410=3600: 完全に削除されたリソース(Gone)は、二度と復活しない確率が高いため 3600秒(1時間) と長めにキャッシュします。
  • 502=5: 上流サーバーのゲートウェイエラーは、オリジンが数秒で復旧する可能性を考慮し、わずか 5秒 という非常に短いTTLに抑え、復旧遅延を防ぎます。

—

TerraformによるInfrastructure as Code (IaC) での宣言的定義

モダンなインフラストラクチャ管理において、手動の gcloud コマンドは検証用や緊急時を除き、基本はTerraform等のIaCでコード管理すべきです。以下に実用的なTerraformのスニペットを示します。

resource "google_compute_backend_service" "web_backend" {
  name                  = "my-web-backend-service"
  protocol              = "HTTP"
  port_name             = "http"
  load_balancing_scheme = "EXTERNAL_MANAGED"

  # Cloud CDNの有効化
  enable_cdn = true

  cdn_config {
    cache_mode = "CACHE_ALL_STATIC"
    # ネガティブキャッシュの有効化
    negative_caching = true

    # 個別のステータスコードに対するTTL設定(秒単位)
    # ※ 実際のプロバイダースキーマのバージョンやAPI仕様に合わせてネスト構造は適宜調整してください
    negative_caching_policy {
      code = 404
      ttl  = 300
    }
    negative_caching_policy {
      code = 502
      ttl  = 5
    }
  }

  backend {
    group = google_compute_instance_group.web_servers.id
  }
}

—

5. 現場のSREが語る:運用上の罠とモニタリングの勘所

ネガティブキャッシュを導入した後に待ち受けている「実際の現場での落とし穴」についても触れておきましょう。

1. キャッシュ無効化(Cache Invalidation / Purging)の罠

「間違えて 500 エラーを長めのTTLでキャッシュしてしまった!」という時にどうするか。Cloud CDNでは、即座にキャッシュを無効化する Invalidation APIを提供しています。
しかし、ネガティブキャッシュされたエラーレスポンスに対しても、通常のURLパス単位でインバリデーションを実行可能です。緊急時には迷わず以下のコマンドやGCPコンソールからパージを叩く準備をしておきましょう。

# 特定のURLパスのキャッシュを即時無効化する
gcloud compute urls invalidate-cdn-caches my-url-map \
    --path="/not-found-target-url" \
    --project=my-production-project

2. ログ監視とメトリクス:オブザーバビリティの確保

ネガティブキャッシュが「どれだけオリジンを救っているか」を可視化することは、インフラエンジニアとしての腕の見せ所です。
Cloud LoggingおよびCloud Monitoringを使い、以下のメトリクスを常に監視・アラート設定しておきましょう。

  • backend_request_count と cache_hit_ratio の相関: エラーレスポンス(404 や 502)が発生した際、Cloud CDNのログにおける jsonPayload.cacheResult フィールドが HIT または EXPIRED_OK になっているか確認します。
  • オリジンへのスループット低下の確認: 攻撃やトラフィック急増時に、オリジン側のWebサーバー(NginxやEnvoy、アプリケーションプロセス)のCPU使用率やコネクション数が安全な閾値内に収まっているかを、PrometheusやDatadog等のAPMツールと突き合わせます。

—

まとめ

Cloud CDNのネガティブキャッシュは、単に「エラー画面を速く返すためのおまけ機能」ではありません。グローバルエッジの強大なリソースを盾にして、不毛なエラー処理の負荷からオリジンサーバーを守り抜くための極めて戦略的なアーキテクチャコンポーネントです。

パケットレベルの挙動、TLSハンドシェイクの効率化、そして何より「ステータスコードごとの適切なTTL設計」を理解し適切にコードに落とし込むことで、システム全体のレジリエンス(回復力)は跳ね上がります。

今日の構築から、ぜひあなたのバックエンドサービスの negative_caching_policy を見直し、より堅牢で無駄のないネットワーク設計をブラッシュアップしてみてください。それでは、良きインフラライフを!

コメント

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