新規のお客様新規アカウントで DNS と CDN の無料プランをご利用いただけます。アカウント作成

キャッシュパージ実践ガイド:キャッシュキーからバリアント単位のパージまで

キャッシュをパージしたのに、まだヒットするのでしょうか。多くの場合、答えはキャッシュキーにあります。Yeap CDN のキャッシュキーの構築方法、クエリ文字列モードの動作、クエリ文字列の有無によって URL パージの削除対象がどう変わるかを解説します。

「キャッシュをパージしたのに、なぜ古いコンテンツが表示されるのでしょうか?」これは CDN の利用者から特によく寄せられる質問の1つで、ほとんどの場合、その答えはキャッシュキーにあります。パージしたオブジェクトと、訪問者がアクセスしているオブジェクトが、同じではない可能性があるのです。このガイドでは、まずキャッシュキーについて説明し、次に Yeap CDN のパージで何が削除されるのか、パージリクエストを裏側でどのように配信しているのかを詳しくご紹介します。

キャッシュキー:エッジがファイルを区別する仕組み

エッジノードは、レスポンスをキャッシュするときにキャッシュキーで識別します。キーは、おおむね次の要素で構成されます。

  • 対象のホスト名。例:www.example.com。
  • 対象のパス。例:/assets/app.js。
  • ドメインに設定されたクエリモードに応じて生成される、正規化されたクエリ文字列。
  • 必要に応じて、コンテンツエンコーディングなど、バリアントを区別する要素も含まれます。

2つのリクエストが同じキャッシュオブジェクトにヒットするのは、キーが完全に一致する場合だけです。そのため、/app.js?v=1 と /app.js?v=2 はデフォルトで別のオブジェクトになります。また、バージョンを示すパラメータを付けると、ブラウザも CDN も新しいファイルを取得するのはこのためです。

クエリ文字列のモード

コンソールの「CDN → ドメイン → キャッシュ」ページで、ドメインがクエリ文字列をどのように扱うかを選択できます。このページには、現在の設定に基づくキャッシュキーのプレビューもリアルタイムで表示されます。

モード動作適している用途
標準(すべて)すべてのパラメータをキーに含めます。?a=3 と ?a=4 は別のオブジェクトになりますパラメータによってコンテンツが変わるサイト
無視クエリ文字列を完全に無視します。どの組み合わせでも同じオブジェクトにヒットします純粋な静的アセット
並べ替えすべてのパラメータを名前順に並べ替えてキーに含めます。?b=2&a=1 と ?a=1&b=2 は同じオブジェクトを共有しますパラメータをさまざまな順序で送信するクライアント
許可リスト指定したパラメータだけをキーに含めます一部のパラメータだけがコンテンツを変える場合
拒否リスト指定したパラメータを除外し、それ以外をすべて含めますutm_source などのトラッキングパラメータを無視する場合

内部では、エッジは常にパラメータをデコードし、名前順に並べ替え、同じ名前が複数ある場合はその値も並べ替えたうえで、再エンコードしてからキーを構築します。そのため、パラメータを保持するどのモードでも、順序の違いだけでオブジェクトが重複することはありません。再エンコードも重要です。デコード後の値に含まれる & や = が曖昧な文字列を生まないようにすることで、異なる2つのリクエストが同じキャッシュキーにならないようにしています。

よくある最適化の例をご紹介します。マーケティング用のリンクにはさまざまなトラッキングパラメータが付いていることが多く、組み合わせが異なるたびに新しいオブジェクトが作られ、ヒット率が下がります。拒否リストモードでこれらを除外すると、通常はヒット率が目に見えて改善します。

パージで実際に削除されるもの

キャッシュ設定ページの右上にある「キャッシュをパージ」をクリックし、2つの選択肢から1つを選びます。

すべてパージ

すべてのエッジノードから、対象ドメインのキャッシュオブジェクトをすべて削除します。大規模なリリースや、何が変わったかわからない場合に使用してください。ただし、その後しばらくはすべてのリクエストがオリジンに向かうため、一時的にオリジンの負荷が増加します。

URL を指定してパージ

完全な URL を1行に1つずつ入力します。パージの動作を理解するうえで重要なのは、次のルールです。

  • クエリ文字列がない場合、たとえば https://www.example.com/list を指定すると、そのパスのすべてのクエリ文字列バリアントを削除します。/list、/list?page=2、/list?page=3 なども含まれます。
  • クエリ文字列がある場合、たとえば https://www.example.com/list?page=2 を指定すると、その1つのバリアントだけを削除します。/list?page=3 はキャッシュに残ります。

クエリ文字列を指定してパージする場合、キャッシュキーの構築とまったく同じルール(同じモード、同じ並べ替え、同じエンコード)で正規化されます。そのため、キャッシュされたリクエストが ?b=2&a=1 であっても、?a=1&b=2 と入力すれば、対象を正確にパージできます。

この動作は、ユーザーのフィードバックを受けて実装しました。初期のパージインデックスはホストとパスだけを比較していたため、?a=3 をパージして成功と表示されても、オブジェクトへのヒットが続くことがありました。キャッシュキーにはクエリ文字列が含まれているのに、パージ時の照合には含まれていなかったためです。現在は、すべてのパージインデックスエントリに正規化済みのクエリ文字列を記録し、バリアント単位で照合しています。

エッジのパージモデルは、プレフィックス、ワイルドカード、タグによる照合にも対応しています。現在、コンソールではサイト全体のパージと URL を指定したパージを利用できます。

パージリクエストがすべてのノードに届く仕組み

確定すると、コンソールはほぼ即座に応答を返します。HTTP リクエストの処理中に、同期的にパージを配信しているわけではないためです。

  1. コントロールプレーンは、パージジョブ(ドメインとパスの一覧)を Redis ベースのバックグラウンドキューに入れ、すぐに応答を返します。
  2. キューのコンシューマーは、そのドメインを配信するエッジノードへジョブを並列配信し、失敗した場合は自動で再試行します。
  3. キュー自体が利用できない場合は、コントロールプレーンが同期配信にフォールバックするため、パージが失われることはありません。

エッジノードでパージを完了するには、2つの処理が必要です。まず、パージインデックスから一致するストレージキーをすべて探し、次に、それらのオブジェクトをキャッシュストレージから削除するとともに、メモリ内のホット層からも削除します。複数の配信チャネルが互いに干渉しないよう、非同期コンテキストでストレージから確実に削除できるチャネルだけがインデックスを変更します。その他のチャネルは、インデックスを変更せずに照合を行い、ホット層だけをクリアします。どのチャネルが先に到着しても、最終的にパージが完了します。

確認方法

エッジのレスポンスには X-Cache-Status ヘッダーが含まれます。パージ後に curl で確認してください。

curl -sI "https://www.example.com/list?page=2" | grep -i x-cache-status
# first request after the purge: X-Cache-Status: MISS
# request again:                 X-Cache-Status: HIT

パージ後も古いコンテンツが表示される場合は、次の順序で確認してください。

  • 原因はブラウザキャッシュでしょうか。エッジのパージでは、訪問者のブラウザにすでにキャッシュされているコピーは削除されません。curl またはプライベートウィンドウでテストしてください。
  • 入力した URL のホスト名は、実際のリクエストと同じでしょうか。example.com と www.example.com のキャッシュは別です。
  • オリジンがまだ古いコンテンツを配信していないでしょうか。パージ後、エッジはオリジンから再取得します。オリジンの前段に別のキャッシュがある場合は、そちらも更新する必要があります。

ベストプラクティス:パージへの依存をできる限り減らす

パージは便利なツールですが、静的アセットで最も確実なのは、コンテンツが変わると URL も変わるようにすることです。

  • app.3f9a1c.js のようにコンテンツのハッシュを含むファイル名を使い、キャッシュの有効期間を長く設定します。新しいバージョンには新しい URL が付くため、パージは不要です。
  • 入口となる HTML ページのキャッシュ有効期間は短くし、新しいアセットの URL がすぐに反映されるようにします。
  • パージが必要な場合は、URL を指定したパージを優先し、サイト全体のパージは広範な変更のときに使います。

キャッシュキーを理解すれば、パージを推測に頼る必要はなくなります。パージしたキーに対応するオブジェクトが削除されるのです。

Yeap Cloud で開発を始める

新規アカウントで DNS と CDN の無料プランをご利用いただけます。

無料登録