Apache Traffic Serverのキャッシュ設定
Apache Traffic Serverを利用する場合、注意したいのがキャッシュの設定だ。特に動的なコンテンツを配信するサイトや、ログインなどが必要でユーザー毎に異なるコンテンツを送信する場合、この設定を間違えると情報漏洩などに繋がる可能性もある。今回はTraffic Serverのキャッシュ設定について説明する。
Apache Traffic Serverにおけるキャッシュの考え方
本記事前編で紹介したとおり、Traffic Serverはクライアントとコンテンツを配信するWebサーバー(オリジンサーバー)を中継し、さらにその際にコンテンツをキャッシュする仕組みを持っている。これによってキャッシュ済みURLへのリクエストについてはオリジンサーバーにリクエストを送ること無しにレスポンスを返せるようになり、オリジンサーバーの負荷軽減やレスポンス速度の向上が期待できるのだが、こうしたアーキテクチャを取る場合に注意したいのが、オリジンサーバーで配信されるコンテンツの中身が変更された場合にキャッシュが十分な速度で更新されるかどうかだ。たとえば短い間隔で更新されるようなコンテンツの場合、キャッシュの有効期間を長く設定してしまうと更新がクライアントに反映されるのが遅くなってしまう。いっぽうであまり更新されないコンテンツに対し、キャッシュの有効時間を短く設定してしまうとキャッシュ効果が薄れてしまう。
Traffic Serverではさまざまなケースに対応するため、多くのキャッシュ関連パラメータが用意されており、さらにURLやオリジンサーバー毎に異なるキャッシュ設定を適用できるようになっている。
Apache Traffic Serverのキャッシュアーキテクチャ
キャッシュ設定について詳しく解説する前に、Traffic Serverの基本的なキャッシュアーキテクチャについて紹介しておこう。Traffic Serverではオリジンサーバーに対しなるべくコンテンツのリクエストを行わないようにしながらキャッシュの有効性を確認できるような仕組みが導入されている。
Traffic Serverは、キャッシュが許可されているURLに対するリクエストを受けると、まずそのリクエストのキャッシュが許可されているかどうかをチェックする。Traffic Serverのデフォルト設定では基本的にはすべてのリクエストがキャッシュされるように設定されているが、たとえばクライアントがリクエスト内に「Cache-Control:」ヘッダーでキャッシュを利用しないよう明示するケースがある。また、サーバー側の設定によって特定の条件に合致するリクエストに対してはキャッシュを行わないように設定することが可能だ。もしキャッシュが許可されていなければ、オリジンサーバーにリクエストを送信してその結果をそのままクライアントに転送する。
もしキャッシュが許可されていれば、続いてキャッシュデータベース内にそのコンテンツが保存されているかどうかを確認する。もしキャッシュデータベース内にそのコンテンツが存在しなければ、オリジンサーバーにリクエストを行ってコンテンツを取得し、それをクライアントに送信するとともにキャッシュデータベース内に保存する(図1)。
いっぽう、キャッシュデータベース内にそのコンテンツが存在していた場合、次にそのキャッシュの「新鮮さ」(stale)を確認する。もし「新鮮」であれば、キャッシュから取り出したデータをクライアントに送信する(図2)。
もしコンテンツが「新鮮」でなければ、Traffic Serverはオリジンサーバーに「If-Modified-Since」ヘッダ付きのリクエストを送信してコンテンツが更新されていないかを確認する(図3)。
Webサーバーはこのヘッダ付きのリクエストを受け取った場合、コンテンツが指定した日付以降に更新されていなければコンテンツを送信する代わりに「304(not modified)」というHTTPステータスコード返送する。この場合、キャッシュに格納されているコンテンツはまだ有効であるため、Traffic Serverはキャッシュから取り出したデータをクライアントに送信するとともに、キャッシュの新鮮さの期限を更新する。
もしオリジンサーバーが304以外のレスポンスを返した場合、Traffic Serverはオリジンサーバーからコンテンツを取得し、キャッシュに保存すると同時にクライアントに送信する(図4)。なお、オリジンサーバーがTraffic Serverからの問い合わせに応答しない場合、「111 Revalidation Failed」レスポンスでキャッシュされたコンテンツを送信する。
「新鮮さ」の判別アルゴリズム
さて、Traffic Serverではこのような手順でキャッシュの制御を行っているのだが、それではTraffic Serverではどのようにして「新鮮さ」を判定するのだろうか。
Traffic Serverがまず指標として使用するのが、Webサーバーがレスポンスを返す際に付与する「Expires:」ヘッダや「Cache-Control:」ヘッダだ。Expires:ヘッダはそのコンテンツの有効期限を時刻で指定するもので、Traffic Serverは現在時刻がこの時刻よりも後の場合、キャッシュが新鮮ではないと判断する。また、Cache-Control:ヘッダはキャッシュの挙動を制御するためのヘッダで、複数のパラメータが指定できる。もしCache-Control:ヘッダ内にキャッシュ期限を設定する「max-age=」パラメータが指定されていた場合、そのキャッシュが作成/更新されてから指定した時間(秒)の間はキャッシュが新鮮であると判断される。たとえば以下のようなヘッダが付与されていた場合、キャッシュが新鮮である期間は60秒となる。
Cache-Control: max-age=60
Expires:ヘッダやCache-Control:ヘッダのmax-ageパラメータが指定されていない場合、そのコンテンツの作成日を示す「Date:」ヘッダや、最終更新日を示す「Last-Modified:」ヘッダの情報を使用し、次の式で新鮮である期間が算出される。
(現在時刻 - 作成日/最終更新日)× 係数
ここで、係数はデフォルトでは0.1となっている(設定で変更可能)。たとえば作成日が2017年1月1日0時、現在時刻が2017年1月11日0時だった場合、新鮮である期間は1日間となる。
(2017年1月11日 - 2017年1月1日) × 0.1 =10日間×0.1 =1日間
一見すると意味が分かりにくいが、作成日/最終更新日から時間が経っているコンテンツは更新頻度が少ないものと判断し、より長い期間新鮮であると判断するという考え方だ。
また、Date:ヘッダおよびLast-Modified:ヘッダの両方がない場合、あらかじめ設定されている新鮮である期間の最大値/最小値を使用して判断を行うことになる。
なお、クライアントから送られたリクエストでキャッシュ制御を指定するCache-Control:ヘッダが指定されていた場合、キャッシュの新鮮さを判断する際にそこで指定されたパラメータが使用される。たとえば「min-fresh」パラメータが指定されていた場合、コンテンツの最終更新日(最終更新日の情報がない場合は作成日)からここで指定された数値(秒)以上の時間が経過していれば、強制的にTraffic Serverはそのコンテンツが新鮮でないと判断する。いっぽう、「max-stale」パラメータが指定されていた場合、もしTraffic Serverがそのコンテンツについて新鮮でないと判断しても、そのコンテンツが更新されているかどうかをオリジンサーバーに問い合わせること無しにキャッシュからの配信を行えるようになる。
Apache Traffic Serverにおけるキャッシュ条件のカスタマイズ
Traffic Serverでは、以上のように「新鮮さ」というパラメータを用いてキャッシュを管理している。しかし、サイトによってはキャッシュされると問題が発生するページなども存在する。さらに、静的なページはなるべく長時間キャッシュを保持してもらい、動的に生成されるページはキャッシュの保持時間を短くしたい、といった要求もあるだろう。続いては、こういったキャッシュ条件をカスタマイズする方法について紹介する。
キャッシュが行われないコンテンツ
Traffic Serverのデフォルト設定では、リクエストヘッダでキャッシュを行わないよう指示されているリクエストに対するレスポンスや、レスポンスヘッダでキャッシュに関する特定の設定が行われているレスポンスについてはキャッシュを行わない。
まずリクエストヘッダについてだが、下記のものが付与されている場合Traffic Serverはキャッシュを利用せず、毎回オリジンサーバーにリクエストを転送してその結果をクライアントに送信する。また、そのコンテンツのキャッシュも行わない。
- Cache-Control:ヘッダに「no-cache」もしくは「no-store」が指定されている
- 「Authorization:」ヘッダが付与されている
ここで挙げられている「Authorization:」ヘッダは、BASIC認証などの認証情報を送信するために使われるものだ。また、オリジンサーバーが送信するレスポンスヘッダ内に次のものが付与されている場合も、そのコンテンツのキャッシュは行わない。
- Cache-Control:ヘッダに「no-store」もしくは「private」、「no-cache」が指定されている
- WWW-Authenticate:ヘッダが付与されている
- Set-Cookie:ヘッダが付与されている
- Expires:ヘッダの値が0、もしくは過去の日付
WWW-Authenticate:ヘッダは、BASIC認証などの認証を要求するヘッダだ。また、Set-Cookie:ヘッダはCookieを送信するためのヘッダだ。これらが付与されているリクエストについても、クライアントによってコンテンツが変わる可能性があるためにキャッシュされないようになっている。
ただし、これらの挙動についてはTraffic Serverの設定によって変更することができる。たとえばリクエストヘッダによる「no-cache」指定は、「proxy.config.http.cache.ignore_client_no_cache」パラメータを1にすることで無視できる。また、レスポンスヘッダの「no-cahce」指定は「proxy.config.http.cache.ignore_server_no_cache」パラメータを1にすることで無視できる。
キャッシュ条件や「新鮮さ」の判断基準を変更する
キャッシュを行うかどうかの判断や新鮮さの判断基準などは、records.configファイルなどで設定できるパラメータによって変更できる。関連するパラメータは多くあるが、主な物としては表1のものがある。
スコープ | パラメータ名 | 型 | 説明 | 指定できる値 | デフォルト値 |
---|---|---|---|---|---|
CONFIG | proxy.config.http.cache.http | INT | キャッシュの有効/無効を設定 | 0(無効)、1(有効) | 1 |
CONFIG | proxy.config.http.cache.allow_empty_doc | INT | レスポンスボディのないレスポンスをキャッシュするかどうかを設定。Content-Lengthヘッダが指定されている場合のみ有効 | 0(キャッシュしない)、1(キャッシュする) | 1 |
CONFIG | proxy.config.http.cache.ignore_client_no_cache | INT | クライアントからのキャッシュバイパス要求を無視するかどうかを設定 | 0(無視しない)、1(無視する) | 1 |
CONFIG | proxy.config.http.cache.ignore_server_no_cache | INT | オリジンサーバーからのキャッシュバイパス要求を無視するかどうかを設定 | 0(無視しない)、1(無視する) | 0 |
CONFIG | proxy.config.http.cache.cache_responses_to_cookies | INT | Cookie付きのリクエストに対するレスポンスをキャッシュするかどうかを設定 | 0(キャッシュしない)、1(すべてをキャッシュ)、2(画像のみキャッシュ)、3(content-typeがtext以外のすべてをキャッシュ) | 1 |
CONFIG | proxy.config.http.cache.ignore_authentication | INT | WWW-Authenticationヘッダ付きのレスポンスをキャッシュするかどうかを設定 | 0(キャッシュする)、1(キャッシュせず、「WWW-Authentication」ヘッダを削除して無視する) | 0 |
CONFIG | proxy.config.http.cache.cache_urls_that_look_dynamic | INT | .aspで終わったり、「?」や「;」、「cgi」を含むURLに対するレスポンスをキャッシュするどうかを設定 | 0(キャッシュしない)、1(キャッシュする) | 1 |
CONFIG | proxy.config.http.cache.when_to_revalidate | INT | キャッシュされたコンテンツの「新鮮さ」の判定方法を設定 | 0(キャッシュ設定やヘッダの内容で判断)、1(ヘッダの内容でのみ判断)、2(常に新鮮でないものとする)、3(常に新鮮だとする)、4(0と同様だが、リクエストにIf-Midified-Since:ヘッダが存在する場合は必ずオリジンサーバーへの問い合わせを行う) | 0 |
CONFIG | proxy.config.http.cache.required_headers | INT | ヘッダに応じてキャッシュの挙動を変えるかどうかを設定 | 0(すべてのレスポンスは原則としてキャッシュ可能)、1(「Last-Modified」が設定されるか、「Expires」、「Cache-Control」ヘッダなどで明示的にキャッシュの持続時間が設定されたレスポンスの場合のみキャッシュ可能)、2(「Expires」、「Cache-Control」ヘッダなどで明示的にキャッシュの持続時間が設定されたレスポンスの場合のみキャッシュ可能) | 2 |
CONFIG | proxy.config.http.cache.max_stale_age | INT | Cache-Control:ヘッダのmax-ageパラメータでキャッシュが新鮮かどうかを判断する際に、キャッシュが新鮮でないとする最大期間を秒で設定する | 604800 | |
CONFIG | proxy.config.http.cache.heuristic_min_lifetime | INT | 作成日や最終更新日でキャッシュが新鮮かどうかを判断する際に、新鮮であると判断する最小期間を秒で指定する | 3600 | |
CONFIG | proxy.config.http.cache.heuristic_max_lifetime | INT | 作成日や最終更新日でキャッシュが新鮮かどうかを判断する際に、新鮮であると判断する最大期間を秒で指定する | 86400 | |
CONFIG | proxy.config.http.cache.heuristic_lm_factor | FLOAT | 作成日や最終更新日でキャッシュが新鮮かどうかを判断する際に使用する係数 | 0.1 |
ここではすべてのキャッシュを無効化する設定や、Cookieが指定されたリクエストに対するレスポンスをキャッシュするかどうかといった設定を行える。これに加えて、前述したキャッシュの新鮮さを判断する際に使用するパラメータについてもここで設定が可能だ。
この中でも、特に注意したいのがCookie付きのリクエストに対するレスポンスをキャッシュするかどうかを決める「proxy.config.http.cache.cache_responses_to_cookies」パラメータだ。デフォルトの設定ではcookie付きのリクエストについてもキャッシュしてしまう可能性がある。この場合でも、前述の通りレスポンスヘッダによって特定のレスポンスについてはキャッシュしないよう設定できるのだが、Webアプリケーションなどが正しくこれらのヘッダーを出力するかどうか不安がある場合は、画像などのコンテンツのみをキャッシュするよう設定を変更しておくと良いだろう。
特定のURLに対し明示的にキャッシュを禁止する
リクエスト/レスポンスによるキャッシュ制御や設定ファイルによる包括的なキャッシュ設定に加えて、URL単位でキャッシュの有効/無効を設定することも可能だ。この設定は、「cache.config」ファイルで行える。
このファイルでは、次のフォーマットで設定を行うようになっている。
<primary_destination>=<値> <secondary_specifier>=<値> <パラメータ>=<値>
ここで、「primary_destination」はドメインやホスト名、IPアドレスなどを指定するもので、「secondary_specifier」はhttp/httpsやポート、URLのパスなどを指定するものだ(表2、3)。
パラメータ名 | 説明 |
---|---|
dest_domain | ドメイン名 |
dest_host | ホスト名 |
dest_ip | IPアドレス |
url_regex | URLにマッチさせる正規表現 |
パラメータ名 | 説明 |
---|---|
port | ポート番号 |
scheme | スキーマ(httpもしくはhttps) |
prefix | URLのパス部分の接頭辞 |
subffix | URLのパス部分の接尾辞 |
method | リクエストメソッド(get、postなど) |
time | 時間(「08:00-14:00」のような形で指定) |
src_ip | クライアントのIPアドレス |
また、「パラメータ」はprimary_distinationおよびsecondary_specifierで指定した条件にマッチしたリクエストに対しどういった処理を行うかを指定するものだ。ここでは以下のものが指定できる。
- 「action」
- 「cache-responses-to-cookies」
- 「pin-in-cache」
- 「revalidate」
- 「ttl-in-cache」
まず「action」だが、これは条件にマッチしたリクエストについてキャッシュの挙動を変更するためのもので、値としては表4のものが指定できる。
パラメータ名 | 説明 |
---|---|
never-cache | キャッシュを行わない |
ignore-client-no-cache | クライアントからのリクエスト内の「Cache-Control: no-cache」ヘッダを無視する |
ignore-server-no-cache | サーバーからのレスポンス内の「Cache-Control: no-cache」ヘッダを無視する |
ignore-no-cache | クライアントからのリクエストおよびサーバーからのレスポンス両方の「Cache-Control: no-cache」ヘッダを無視する |
cluster-cache-local | クラスタの各ノードがローカルにキャッシュを保存することを許可する |
たとえばその条件にマッチしたリクエストに対しキャッシュを行わせたくない場合、「action=never-cache」と指定すれば良い。
また、「cache-responses-to-cookies」はCookie付きのリクエストに対するレスポンスをキャッシュするかどうかを指定するものだ。records.config内の「proxy.config.http.cache.cache_responses_to_cookies」パラメータと同じく、0(キャッシュしない)、1(すべてをキャッシュ)、2(画像のみキャッシュ)、3(content-typeがtext以外のすべてをキャッシュ)のいずれかが指定できる。
そのほか、キャッシュを保持する(「pin」する)期間を指定する「pin-in-cache」、キャッシュが「新鮮」である期間を設定する「revalidate」、キャッシュの最大有効期間を設定する「ttl-in-cache」といったパラメータも指定できる。「pin-in-cache」パラメータや「revalidate」パラメータ、「ttl-in-cache」パラメータでは単位としてd(日)、h(時間)、m(分)、s(秒)が利用でき、「1h15m20s」のように混在した指定も可能だ。
Vary:ヘッダへの対応
WebサーバーやWebアプリケーションの設定によっては、たとえば言語を指定する「Accept-Language:」など、特定のリクエストヘッダに応じて出力が変わる場合がある。この場合、Webサーバーはレスポンスの「Vary:」ヘッダで出力に影響するヘッダの情報を出力することが推奨されているのだが、Traffic ServerでもこのVary:ヘッダの内容をチェックしてコンテンツを適切にキャッシュしたり、リクエストに対して適切なコンテンツを配信する仕組みが用意されている。この機能はデフォルトでは無効になっているが、表4のパラメータを変更することで有効にできる。
スコープ | パラメータ名 | 型 | 説明 | 指定できる値 | デフォルト値 |
---|---|---|---|---|---|
CONFIG | proxy.config.http.cache.enable_default_vary_headers | INT | Vary:ヘッダを参照して単一のURLに対し複数のキャッシュを保持するかどうかを設定 | 0(複数のキャッシュを保持しない)、1(複数のキャッシュを保持する) | 0 |
CONFIG | proxy.config.http.cache.vary_default_text | STRING | テキストコンテンツについて、ここで指定したヘッダに対してのみ、複数のキャッシュの保持を有効にする | ヘッダ名 | なし |
CONFIG | proxy.config.http.cache.vary_default_images | STRING | 画像コンテンツについて、ここで指定したヘッダに対してのみ、複数のキャッシュの保持を有効にする | ヘッダ名 | なし |
CONFIG | proxy.config.http.cache.vary_default_other | STRING | テキスト/画像以外のコンテンツについて、ここで指定したヘッダに対してのみ、複数のキャッシュの保持を有効にする | ヘッダ名 | なし |
CONFIG | proxy.config.cache.limits.http.max_alts | INT | 1つのURLに対しキャッシュできる最大数を指定する | 最大数 | 5 |
たとえばオリジンサーバーが「Accept-Language:」ヘッダの値によって異なるコンテンツを返す場合、「proxy.config.http.cache.enable_default_vary_headers」パラメータを1に設定し、「proxy.config.http.cache.vary_default_text」に「Accept-Language」を設定することで、同一のURLに対しAccept-Language:ヘッダの内容に応じた複数のキャッシュを保持させることが可能になる。
そのほかにも多数の設定が可能
今回は主にキャッシュ関連の設定について紹介したが、これ以外にもTraffic Serverには多数の設定項目が用意されている。また、プラグインで機能を強化したり、クラスタ構成を取ることも可能だ。これらはドキュメントの管理者ガイドや設定ファイルリファレンスで詳しく説明されているので、そちらを参照すると良いだろう。