CDNサーバーのキャッシュ最適化

動的コンテンツ分類によるキャッシュ未適用現象

最近、ゲームサーバーのAPI応答速度を分析していたところ、静的ファイルとは異なり、JSONデータがキャッシュされない現象を発見した。原因は、Cloudflareの基本ポリシー上、HTMLやJSONのようなテキストベースのデータが動的コンテンツとして分類されるためであった。 応答ヘッダーの CF-Cache-Status: DYNAMIC ステータスは、ユーザーのリクエストがCDNをバイパスしてOriginサーバーに直結していることを意味し、結果としてOriginサーバーの負荷を増大させる要因となる。

https://developers.cloudflare.com/cache/concepts/default-cache-behavior Default cached file extensions "Cloudflare only caches based on file extension and not by MIME type. The Cloudflare CDN does not cache HTML or JSON by default. Additionally, by default Cloudflare caches a website's robots.txt."

sequenceDiagram participant U as クライアント participant CF as Cloudflare Edge participant O as Originサーバー Note over CF: 基本ポリシー: JSONキャッシュ非対応 (DYNAMIC) U->>CF: GET /char.json リクエスト CF->>O: リクエストバイパス O-->>CF: JSONデータ返却 CF-->>U: JSONデータ応答 (Cache-Status: DYNAMIC)

第1次案: Cache Rulesを活用した強制キャッシュ導入

静的アセット(CSS, JS)はファイル名のハッシュを通じてバージョン管理(Cache Busting)が容易だが、APIエンドポイントはリソースの固有識別子としてURLが固定されている必要があるため、ファイル名を変更する方式を適用するのは難しい。

Cache Busting ユーザーのブラウザに最新バージョンのファイルをダウンロードさせる強制的な方法

上記の問題を解決するための一次的なアプローチとして、CloudflareのCache Rules設定を活用する。これは特定の拡張子(*.json)を持つリクエストに対してEdgeキャッシュTTLを強制適用し、Originへのリクエスト頻度を減らす。

  • s-maxage (Edge TTL): 中間サーバーのキャッシュ有効時間
  • max-age (Browser TTL): ユーザーブラウザのキャッシュ有効時間

トレードオフ - データ整合性の問題

しかし、長いTTL設定は必然的にデータの鮮度低下という副作用を伴う。ゲームバランスパッチなどで元データが修正されても、固有IDベースのURL構造が維持される限り、CDNとブラウザはファイルの変更事実を認識できない。これは、設定された長い s-maxage 期間中、Staleデータがユーザーに継続的に送信される結果を招き、サービス運営において致命的な情報不一致問題を引き起こす。

第2次案: 自動化されたCache Purge戦略

上記の問題を根本的に解決するため、デプロイパイプラインにキャッシュ削除ロジックを統合する。

sequenceDiagram autonumber actor User as クライアント participant CF_Edge as CDN participant O as ストレージ participant GA as Origin actor Dev as 開発者 rect rgba(235, 197, 145, 0.1) CF_Edge-->>User: GET /char.json Dev->>GA: バージョンアップデート activate GA GA->>O: 最新バージョンデプロイ GA->>CF_Edge: purge_cache API呼び出し GA->>User: 信号送信 deactivate GA end rect rgba(82, 129, 172, 0.1) User->>CF_Edge: GET /char.json CF_Edge->>O: Revalidate O-->>CF_Edge: 最新データ返却 CF_Edge-->>User: 最新データ応答 end