Webキャッシングの基本:用語、HTTPヘッダー、およびキャッシング戦略

前書き

インテリジェントコンテンツキャッシュは、サイトの訪問者のエクスペリエンスを向上させる最も効果的な方法の1つです。 キャッシュ、または以前のリクエストからのコンテンツを一時的に保存することは、HTTPプロトコル内で実装されるコアコンテンツ配信戦略の一部です。 配信パス全体のコンポーネントは、コンテンツに対して宣言されたキャッシングポリシーに従って、すべてのアイテムをキャッシュして後続のリクエストを高速化できます。

このガイドでは、Webコンテンツキャッシングの基本概念のいくつかについて説明します。 これは主に、キャッシュポリシーを選択して、インターネット全体のキャッシュがコンテンツを正しく処理できるようにする方法について説明します。 キャッシングが提供する利点、注意すべき副作用、およびパフォーマンスと柔軟性の最適な組み合わせを提供するために採用するさまざまな戦略について説明します。

キャッシングとは

キャッシングは、後続のリクエストを高速化するために再利用可能な応答を保存するための用語です。 さまざまなタイプのキャッシュが利用可能で、それぞれに独自の特性があります。 アプリケーションキャッシュとメモリキャッシュは両方とも、特定の応答を高速化する能力があるため人気があります。

このガイドの焦点であるWebキャッシングは、異なるタイプのキャッシュです。 Webキャッシングは、システム全体として認識される応答性を改善しながら、ネットワークトラフィックを最小限に抑えることを目的としたHTTPプロトコルのコア設計機能です。 キャッシュは、元のサーバーからブラウザまでのコンテンツのすべてのレベルで見つかります。

Webキャッシュは、特定のルールに従って要求のHTTP応答をキャッシュすることにより機能します。 キャッシュされたコンテンツに対する後続のリクエストは、リクエストをWebサーバーに送り返すのではなく、ユーザーに近いキャッシュから実行できます。

利点

効果的なキャッシングは、コンテンツコンシューマーとコンテンツプロバイダーの両方を支援します。 キャッシュがコンテンツ配信にもたらす利点のいくつかは次のとおりです。

  • Decreased network costs:コンテンツは、コンテンツコンシューマーとコンテンツオリジンの間のネットワークパスのさまざまなポイントでキャッシュできます。 コンテンツがコンシューマの近くにキャッシュされると、リクエストによってキャッシュを超えるネットワークアクティビティが追加されることはありません。

  • Improved responsiveness:ネットワーク全体のラウンドトリップが必要ないため、キャッシュを使用するとコンテンツをより高速に取得できます。 ブラウザのキャッシュのように、ユーザーの近くに保持されるキャッシュにより、この取得をほぼ瞬時に行うことができます。

  • Increased performance on the same hardware:コンテンツが発信されたサーバーの場合、積極的なキャッシュを許可することで、同じハードウェアからより多くのパフォーマンスを引き出すことができます。 コンテンツ所有者は、配信パスに沿って強力なサーバーを活用して、特定のコンテンツの負荷を簡単に受けることができます。

  • Availability of content during network interruptions:特定のポリシーでは、キャッシュを使用して、オリジンサーバーから短期間利用できない場合でも、エンドユーザーにコンテンツを提供できます。

用語

キャッシングを扱うとき、見慣れないかもしれないいくつかの用語があります。 一般的なもののいくつかを以下に示します。

  • Origin server:オリジンサーバーはコンテンツの元の場所です。 Webサーバー管理者として機能している場合、これが制御するマシンです。 要求ルートに沿ってキャッシュから取得できなかったコンテンツを処理し、すべてのコンテンツのキャッシュポリシーを設定します。

  • Cache hit ratio:キャッシュの有効性は、キャッシュヒット率またはヒット率の観点から測定されます。 これは、キャッシュから取得できるリクエストと、行われたリクエストの合計の比率です。 キャッシュヒット率が高いということは、高い割合のコンテンツをキャッシュから取得できたことを意味します。 これは通常、ほとんどの管理者にとって望ましい結果です。

  • Freshness:鮮度は、キャッシュ内のアイテムがクライアントに提供する候補と見なされるかどうかを説明するために使用される用語です。 キャッシュ内のコンテンツは、キャッシュポリシーで指定された鮮度の時間枠内にある場合にのみ応答に使用されます。

  • Stale content:キャッシュ内のアイテムは、キャッシュポリシーのキャッシュの鮮度設定に従って期限切れになります。 期限切れのコンテンツは「古くなっています」。 一般に、期限切れのコンテンツを使用してクライアントの要求に応答することはできません。 オリジンサーバに再接続して、新しいコンテンツを取得するか、少なくともキャッシュされたコンテンツがまだ正確であることを確認する必要があります。

  • Validation:有効期限を更新するために、キャッシュ内の古いアイテムを検証できます。 検証では、オリジンサーバーにチェックインして、キャッシュされたコンテンツがまだ最新バージョンのアイテムを表しているかどうかを確認します。

  • Invalidation:無効化は、指定された有効期限より前にキャッシュからコンテンツを削除するプロセスです。 これは、アイテムが元のサーバーで変更されており、キャッシュに古いアイテムがあるとクライアントに重大な問題が発生する場合に必要です。

他にも多くのキャッシング用語がありますが、上記の用語は開始に役立つはずです。

キャッシュできるもの

特定のコンテンツは、他のコンテンツよりもキャッシングに適しています。 ほとんどのサイトで非常にキャッシュに優しいコンテンツは次のとおりです。

  • ロゴとブランド画像

  • 一般的な回転しない画像(ナビゲーションアイコンなど)

  • スタイルシート

  • 一般的なJavaScriptファイル

  • ダウンロード可能なコンテンツ

  • メディアファイル

これらはめったに変更されない傾向があるため、より長い期間キャッシュされることでメリットが得られます。

キャッシュに注意する必要があるいくつかのアイテムは次のとおりです。

  • HTMLページ

  • 画像の回転

  • 頻繁に変更されるJavascriptとCSS

  • 認証Cookieで要求されたコンテンツ

ほとんど決してキャッシュされるべきではないいくつかのアイテムは次のとおりです。

  • 機密データに関連する資産(銀行情報など)

  • ユーザー固有で頻繁に変更されるコンテンツ

上記の一般的な規則に加えて、さまざまな種類のコンテンツを適切にキャッシュできるポリシーを指定することができます。 たとえば、認証されたすべてのユーザーがサイトの同じビューを見る場合、そのビューをどこにでもキャッシュできる可能性があります。 認証されたユーザーが、しばらくの間有効なサイトのユーザー依存ビューを見る場合、ユーザーのブラウザーにキャッシュするように指示できますが、中間キャッシュにはビューを保存しないように指示できます。

Webコンテンツがキャッシュされる場所

コンテンツは、配信チェーン全体のさまざまなポイントでキャッシュできます。

  • Browser cache:Webブラウザ自体が小さなキャッシュを維持します。 通常、ブラウザは、キャッシュする最も重要なアイテムを指定するポリシーを設定します。 これは、ユーザー固有のコンテンツ、またはダウンロードに費用がかかり、再度要求される可能性が高いと思われるコンテンツである可能性があります。

  • Intermediary caching proxies:クライアントとインフラストラクチャの間にあるサーバーは、必要に応じて特定のコンテンツをキャッシュできます。 これらのキャッシュは、ISPまたは他の独立した当事者によって維持される場合があります。

  • Reverse Cache:サーバーインフラストラクチャは、バックエンドサービス用に独自のキャッシュを実装できます。 これにより、リクエストごとにバックエンドサーバーにアクセスする代わりに、連絡先からコンテンツを提供できます。

これらの各場所は、独自のキャッシュポリシーとコンテンツオリジンで設定されたポリシーに従って、アイテムをキャッシュできます。

キャッシングヘッダー

キャッシングポリシーは、2つの異なる要因に依存しています。 キャッシングエンティティ自体が、受け入れ可能なコンテンツをキャッシュするかどうかを決定します。 キャッシュすることが許可されているよりも少ないが、それ以上ではないことを決定できます。

キャッシュ動作の大部分は、コンテンツ所有者によって設定されるキャッシュポリシーによって決定されます。 これらのポリシーは、主に特定のHTTPヘッダーを使用して明確にされています。

HTTPプロトコルのさまざまな反復を通じて、洗練されたさまざまなレベルのいくつかの異なるキャッシュ中心のヘッダーが作成されました。 おそらくまだ注意を払う必要があるものは以下のとおりです。

  • ExpiresExpiresヘッダーは非常に単純ですが、範囲はかなり制限されています。 基本的に、コンテンツの有効期限が切れる将来の時間を設定します。 この時点で、同じコンテンツに対する要求はすべてオリジンサーバーに戻される必要があります。 このヘッダーは、おそらくフォールバックとしてのみ使用するのが最適です。

  • Cache-Control:これはExpiresヘッダーの最新の代替品です。 十分にサポートされており、はるかに柔軟な設計を実装しています。 ほとんどの場合、これはExpiresよりも望ましいですが、両方の値を設定しても問題はありません。 Cache-Controlで設定できるオプションの詳細については後で説明します。

  • EtagEtagヘッダーはキャッシュ検証で使用されます。 オリジンは、最初にコンテンツを提供するときに、アイテムに一意のEtagを提供できます。 キャッシュは、有効期限が切れたときに手元にあるコンテンツを検証する必要がある場合、コンテンツに対して持っているEtagを送り返すことができます。 オリジンは、コンテンツが同じであることをキャッシュに通知するか、更新されたコンテンツを(新しいEtagで)送信します。

  • Last-Modified:このヘッダーは、アイテムが最後に変更された時刻を指定します。 これは、新鮮なコンテンツを確保するための検証戦略の一部として使用できます。

  • Content-Length:キャッシュには特に関係ありませんが、Content-Lengthヘッダーは、キャッシュポリシーを定義するときに設定することが重要です。 特定のソフトウェアは、スペースを予約する必要があるコンテンツのサイズが高度にわからない場合、コンテンツのキャッシュを拒否します。

  • Vary:キャッシュは通常、要求されたホストとリソースへのパスを、キャッシュアイテムを格納するためのキーとして使用します。 Varyヘッダーを使用して、リクエストが同じアイテムに対するものであるかどうかを判断するときに、追加のヘッダーに注意を払うようにキャッシュに指示できます。 これは、キャッシュにAccept-Encodingヘッダーによってキーを指定するためにも最も一般的に使用されるため、キャッシュは圧縮されたコンテンツと圧縮されていないコンテンツを区別することができます。

Varyヘッダーに関する余談

Varyヘッダーは、キャッシュ内のエントリを希釈することを犠牲にして、同じコンテンツの異なるバージョンを保存する機能を提供します。

Accept-Encodingの場合、Varyヘッダーを設定すると、圧縮されたコンテンツと圧縮されていないコンテンツを明確に区別できます。 これは、圧縮されたコンテンツを処理できないブラウザにこれらのアイテムを正しく提供するために必要であり、基本的な使いやすさを提供するために必要です。 Accept-EncodingVaryの適切な候補である可能性があることを示す1つの特性は、2つまたは3つの可能な値しかないことです。

User-Agentのようなアイテムは、一見、モバイルブラウザとデスクトップブラウザを区別して、サイトのさまざまなバージョンを提供するための良い方法のように思われるかもしれません。 ただし、User-Agent文字列は非標準であるため、結果として、中間キャッシュに同じコンテンツの多くのバージョンが作成され、キャッシュヒット率が非常に低くなります。 Varyヘッダーは慎重に使用する必要があります。特に、制御する中間キャッシュでリクエストを正規化する機能がない場合(たとえば、コンテンツ配信ネットワークを利用している場合)。

キャッシュ制御フラグがキャッシュに与える影響

上記で、Cache-Controlヘッダーが最新のキャッシュポリシー仕様にどのように使用されるかについて説明しました。 このヘッダーを使用して、複数の異なるポリシー指示を設定できます。複数の指示をコンマで区切ります。

コンテンツのキャッシュポリシーを指示するために使用できるCache-Controlオプションのいくつかは次のとおりです。

  • no-cache:この命令は、キャッシュされたコンテンツをクライアントに提供する前に、リクエストごとに再検証する必要があることを指定します。 これにより、コンテンツはすぐに古くなったものとしてマークされますが、再検証手法を使用してアイテム全体を再度ダウンロードすることを回避できます。

  • no-store:この命令は、コンテンツをキャッシュできないことを示します。 これは、応答が機密データを表す場合に設定するのに適しています。

  • public:これは、コンテンツをパブリックとしてマークします。これは、コンテンツをブラウザーおよび任意の中間キャッシュでキャッシュできることを意味します。 HTTP認証を利用した要求の場合、応答にはデフォルトでprivateのマークが付けられます。 このヘッダーはその設定を上書きします。

  • private:これはコンテンツをprivateとしてマークします。 プライベートコンテンツはユーザーのブラウザによって保存される場合がありますが、notは中間関係者によってキャッシュされる必要があります。 これは多くの場合、ユーザー固有のデータに使用されます。

  • max-age:この設定は、コンテンツを再検証するか、オリジンサーバーからコンテンツを再ダウンロードする前に、コンテンツがキャッシュされる最大有効期間を構成します。 本質的に、これは最新のブラウジングのExpiresヘッダーに置き換わるものであり、コンテンツの鮮度を判断するための基礎となります。 このオプションの値は秒単位で、最大有効有効期間は1年(31536000秒)です。

  • s-maxage:これは、コンテンツをキャッシュできる時間を示すという点で、max-age設定と非常によく似ています。 違いは、このオプションが中間キャッシュにのみ適用されることです。 これを上記と組み合わせると、より柔軟なポリシー構築が可能になります。

  • must-revalidate:これは、max-ages-maxage、またはExpiresヘッダーで示される鮮度情報に厳密に従う必要があることを示します。 古いコンテンツは、いかなる状況でも提供できません。 これにより、ネットワークの中断などのシナリオでキャッシュされたコンテンツが使用されなくなります。

  • proxy-revalidate:これは上記の設定と同じように動作しますが、中間プロキシにのみ適用されます。 この場合、ネットワークの中断時に古いコンテンツを提供するためにユーザーのブラウザを使用できる可能性がありますが、中間キャッシュをこの目的に使用することはできません。

  • no-transform:このオプションは、パフォーマンス上の理由から、どのような状況でも受信したコンテンツを変更できないことをキャッシュに通知します。 これは、たとえば、キャッシュが、オリジンサーバーから受信しなかったコンテンツの圧縮バージョンを圧縮して送信できず、許可されていないことを意味します。

これらをさまざまな方法で組み合わせて、さまざまなキャッシュ動作を実現できます。 相互に排他的な値は次のとおりです。

  • no-cacheno-store、およびいずれかがないことで示される通常のキャッシュ動作

  • publicおよびprivate

両方が存在する場合、no-storeオプションはno-cacheに優先します。 認証されていない要求への応答の場合、publicが暗黙指定されます。 認証された要求への応答の場合、privateが暗黙指定されます。 これらは、Cache-Controlヘッダーに反対のオプションを含めることでオーバーライドできます。

キャッシング戦略の開発

完璧な世界では、すべてが積極的にキャッシュされ、サーバーは時々コンテンツを検証するためにのみ接続されます。 ただし、これは実際には頻繁に行われないため、長期的なキャッシュの実装と変化するサイトの要求への対応とのバランスをとることを目的とした、適切なキャッシュポリシーを設定する必要があります。

一般的な問題

コンテンツの生成方法(ユーザーごとに動的に生成される)またはコンテンツの性質(銀行の機密情報など)により、キャッシングを実装できない、または実装すべきでない状況が多くあります。 キャッシュを設定する際に多くの管理者が直面する別の問題は、新しいバージョンが公開されていても、コンテンツの古いバージョンが荒廃しており、まだ古くなっていないという状況です。

これらは両方とも頻繁に発生する問題であり、キャッシュのパフォーマンスと提供するコンテンツの精度に深刻な影響を与える可能性があります。 ただし、これらの問題を予測するキャッシュポリシーを開発することにより、これらの問題を軽減できます。

一般的な推奨事項

状況によって、使用するキャッシュ戦略が決まりますが、次の推奨事項は、合理的な判断に導くのに役立ちます。

使用する特定のヘッダーについて心配する前に、キャッシュヒット率を上げるために実行できる特定の手順があります。 いくつかのアイデアがあります:

  • Establish specific directories for images, css, and shared content:コンテンツを専用ディレクトリに配置すると、サイトのどのページからでも簡単に参照できるようになります。

  • Use the same URL to refer to the same items:キャッシュは、ホストと要求されたコンテンツへのパスの両方からキーオフされるため、すべてのページで同じ方法でコンテンツを参照するようにしてください。 前の推奨事項により、これが大幅に簡単になります。

  • Use CSS image sprites where possible:アイコンやナビゲーションなどのアイテムのCSS画像スプライトは、サイトのレンダリングに必要なラウンドトリップの数を減らし、サイトがその単一のスプライトを長期間キャッシュできるようにします。

  • Host scripts and external resources locally where possible:JavaScriptスクリプトやその他の外部リソースを利用する場合、正しいヘッダーがアップストリームに提供されていない場合は、それらのリソースを独自のサーバーでホストすることを検討してください。 ローカルコピーを更新できるように、リソースのアップストリームへの更新を認識する必要があることに注意してください。

  • Fingerprint cache items:CSSやJavascriptファイルなどの静的コンテンツの場合、各アイテムにフィンガープリントを付けることが適切な場合があります。 これは、リソースが変更された場合に新しいリソース名を要求できるように、ファイル名に一意の識別子(多くの場合ファイルのハッシュ)を追加して、要求がキャッシュを正しくバイパスすることを意味します。 HTMLドキュメント内で指紋を作成し、指紋への参照を変更するのに役立つさまざまなツールがあります。

さまざまなアイテムに適切なヘッダーを選択するという点では、以下を参考にしてください。

  • Allow all caches to store generic assets:静的コンテンツおよびユーザー固有ではないコンテンツは、配信チェーンのすべてのポイントでキャッシュでき、キャッシュする必要があります。 これにより、中間キャッシュが複数のユーザーのコンテンツで応答できるようになります。

  • Allow browsers to cache user-specific assets:ユーザーごとのコンテンツの場合、ユーザーのブラウザ内でのキャッシュを許可することは、多くの場合、受け入れられ、有用です。 このコンテンツは、中間キャッシングプロキシでキャッシュするのには適切ではありませんが、ブラウザでキャッシングすると、その後のアクセス中にユーザーがすぐに取得できます。

  • Make exceptions for essential time-sensitive content:時間に敏感なコンテンツがある場合は、上記のルールに例外を設けて、重要な状況で古いコンテンツが配信されないようにします。 たとえば、サイトにショッピングカートがある場合、すぐにカート内のアイテムを反映する必要があります。 コンテンツの性質に応じて、no-cacheまたはno-storeオプションをCache-Controlヘッダーに設定してこれを実現できます。

  • Always provide validators:バリデーターを使用すると、リソース全体を再度ダウンロードしなくても、古いコンテンツを更新できます。 EtagヘッダーとLast-Modifiedヘッダーを設定すると、キャッシュはコンテンツを検証し、元の場所で変更されていない場合はコンテンツを再予約できるため、負荷がさらに軽減されます。

  • Set long freshness times for supporting content:キャッシュを効果的に活用するために、リクエストを満たすためのサポートコンテンツとしてリクエストされた要素には、多くの場合、鮮度の設定が長くなければなりません。 これは一般に、ユーザーが要求したHTMLページをレンダリングするために取り込まれる画像やCSSなどのアイテムに適しています。 鮮度の延長時間を設定し、フィンガープリントと組み合わせることで、キャッシュがこれらのリソースを長期間保存できるようになります。 アセットが変更されると、変更されたフィンガープリントはキャッシュされたアイテムを無効にし、新しいコンテンツのダウンロードをトリガーします。 それまでは、サポートするアイテムを将来的にキャッシュすることができます。

  • Set short freshness times for parent content:上記のスキームを機能させるには、含まれているアイテムの鮮度が比較的短い必要があります。そうでない場合は、キャッシュされない可能性があります。 これは通常、他の補助コンテンツを呼び出すHTMLページです。 HTML自体は頻繁にダウンロードされるため、変更に迅速に対応できます。 その後、サポートコンテンツを積極的にキャッシュできます。

重要なのは、可能な場合は積極的なキャッシュを優先し、将来変更が行われたときにエントリを無効にする機会を残してバランスを取ることです。 サイトには次の組み合わせが含まれている可能性があります。

  • 積極的にキャッシュされたアイテム

  • 鮮度が短いキャッシュ済みアイテムと再検証機能

  • キャッシュすべきではないアイテム

目標は、可能な場合は許容可能なレベルの精度を維持しながら、コンテンツを最初のカテゴリに移動することです。

結論

時間をかけてサイトに適切なキャッシュポリシーが設定されていることを確認すると、サイトに大きな影響を与える可能性があります。 キャッシュを使用すると、同じコンテンツを繰り返し提供することに関連する帯域幅コストを削減できます。 サーバーは、同じハードウェアでより多くのトラフィックを処理することもできます。 おそらく最も重要なことは、クライアントのサイトでのエクスペリエンスがより速くなり、クライアントがより頻繁に戻ってくる可能性があることです。 効果的なWebキャッシュは特効薬ではありませんが、適切なキャッシュポリシーを設定すると、最小限の作業で測定可能な利益を得ることができます。