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

前書き

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

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

キャッシングとは

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

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

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

利点

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

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

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

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

  • ネットワークの中断中のコンテンツの可用性:特定のポリシーでは、オリジンサーバーから短時間利用できない場合でも、キャッシュを使用してコンテンツをエンドユーザーに提供できます。

用語

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

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

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

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

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

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

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

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

キャッシュできるもの

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

  • ロゴとブランド画像

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

  • スタイルシート

  • 一般的なJavaScriptファイル

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

  • メディアファイル

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

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

  • HTMLページ

  • 画像の回転

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

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

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

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

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

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

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

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

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

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

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

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

キャッシングヘッダー

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

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

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

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

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

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

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

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

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

Varyヘッダーに関する余談

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

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

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

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

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

コンテンツキャッシュポリシーを決定するために使用できる `+ Cache-Control`オプションの一部は次のとおりです。

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

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

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

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

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

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

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

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

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

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

  • + no-cache、` + no-store`、およびいずれかの不在によって示される通常のキャッシュ動作

  • + public`および + private`

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

キャッシング戦略の開発

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

一般的な問題

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

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

一般的な推奨事項

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

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

  • 画像、CSS、および共有コンテンツ用の特定のディレクトリを確立:コンテンツを専用ディレクトリに配置すると、サイトの任意のページから簡単にそれらを参照できます。

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

  • 可能な場合はCSS画像スプライトを使用します:アイコンやナビゲーションなどのアイテムのCSS画像スプライトは、サイトをレンダリングするために必要な往復回数を減らし、サイトがその単一スプライトを長時間キャッシュできるようにします。

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

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

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

  • すべてのキャッシュに汎用アセットを保存できるようにする:静的コンテンツおよびユーザー固有ではないコンテンツは、配信チェーンのすべてのポイントでキャッシュできます。 これにより、中間キャッシュが複数のユーザーのコンテンツで応答できるようになります。

  • ブラウザがユーザー固有のアセットをキャッシュできるようにする:ユーザーごとのコンテンツの場合、多くの場合、ユーザーのブラウザー内でキャッシュを許可することは許容でき、便利です。 このコンテンツは、中間キャッシングプロキシでキャッシュするのには適切ではありませんが、ブラウザでキャッシングすると、その後のアクセス中にユーザーがすぐに取得できます。

  • 重要な時間依存コンテンツの例外を作成する:時間依存のコンテンツがある場合は、上記のルールに例外を設定して、期限切れのコンテンツが重大な状況で配信されないようにします。 たとえば、サイトにショッピングカートがある場合、すぐにカート内のアイテムを反映する必要があります。 コンテンツの性質に応じて、これを実現するために + Cache-Control +`ヘッダーで `+ no-cache`または + no-store + `オプションを設定できます。

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

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

  • 親コンテンツの鮮度時間を短く設定:上記のスキームを機能させるためには、含まれるアイテムの鮮度時間を比較的短くするか、キャッシュしない場合があります。 これは通常、他の補助コンテンツを呼び出すHTMLページです。 HTML自体は頻繁にダウンロードされるため、変更に迅速に対応できます。 その後、サポートコンテンツを積極的にキャッシュできます。

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

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

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

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

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

結論

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

前の投稿:Goで文字列をフォーマットする方法
次の投稿:Ubuntu 14.04でgzipモジュールをNginxに追加する方法