PASS アクションの挙動について
Last updated August 01, 2018
Varnish では Pass (キャッシュしない)設定をリクエスト設定で行うのとキャッシュ設定で行うのでは異なる挙動となります。リクエスト設定で Pass を設定すると、 VCL 上では vcl_recv
内で return(pass)
することになります。キャッシュ設定で Pass を設定すると、 vcl_fetch
で return(pass)
されます。キャッシュ設定で Pass を行うのは、Varnish 3+ での return(hit_for_pass)
と同じ動作となります。
リクエスト設定での Pass
リクエスト設定で Pass を作成すると、生成されたVCLの vcl_recv
内に return(pass)
に出力されます。Varnish はオブジェクト内にオブジェクトがキャッシュされていないかどうかの確認(ルックアップ)を行わず、オリジンからのレスポンスもキャッシュされません。
この Pass ではリクエスト共有 (request collapsing) は行われません。通常、同じオブジェクトに対して同時発生したリクエストがキャッシュに存在しない場合、オリジンへのリクエストはひとつのリクエストに集約されます。最初のリクエストがオリジンに送信されている間、そのオブジェクトに対する他のリクエストは、レスポンスが受信されるまでキューに入れられます。リクエストが vcl_recv
で Pass された場合、それらのリクエストはすべてまとめられずに別々のリクエストとしてオリジンに送信されます。
キャッシュ設定での Pass
キャッシュ設定で Pass を作成すると、生成されたVCLの vcl_fetch
内に return(pass)
が出力されます。リクエストのフローのこの時点では、Varnish はルックアップを実行し、オブジェクトがキャッシュに存在しないと判断しています。その後オリジンへリクエストが送られますが、vcl_fetch
でレスポンスがキャッシュすることが出来ないと判断されます。この動作は、Fastly のデフォルトの VCL では、オリジンからのレスポンスに Set-Cookie
ヘッダーが存在する場合などに発生します。
リクエスト共有が無効にならないため、 vcl_fetch
で Pass を行うことはしばしば望ましくないことがあります。リクエストの共有は、Varnish が vcl_recv
の段階ではオブジェクトがキャッシュ出来ないことを認識していないので無効となりません。
例えば vcl_fetch で Pass が設定されているオブジェクトがあったとします。 Varnish がそのオブジェクトに対してリクエストを受け、キャッシュミスが発生すると、そのリクエストはオリジンに送信されます。この時、オリジンからレスポンスを取得する前に同じオブジェクトに対して追加のリクエストを受けた場合、それらのリクエストはすぐにはオリジンには送信されずに、キューに入れられます。
オリジンからのレスポンスが受信( vcl_fetch )され、リクエストが Pass されるべきことを Varnish が認識すると、キューに入れられたリクエストはオリジンに送信されます。
この場合、2人のユーザーが同時にオブジェクトをリクエストするケースでは、1人のユーザーのリクエストが処理されるまで、もう一方のユーザーが待機する必要があります。これに対して、これらのリクエストが vcl_recv
で Pass された場合、どちらのユーザにも待ち時間は発生しません。
この問題を回避するために、リクエストが vcl_fetch
で Pass されると、Varnish はhit-for-pass オブジェクト
と呼ばれるものを作成します。これらのオブジェクトも TTL を持つことが可能で、TTLが有効な間にこのオブジェクトに発生したリクエストは、vcl_recv
で Pass されたかのようにそれらのリクエストを処理します。このため、 vcl_fetch
で Pass を行う際にも、用途にあった TTL を設定することが重要となります。その後に発生するオブジェクトに対するすべてのリクエストは、hit-for-pass オブジェクトの TTL が期限切れになるまで Pass されます。hit-for-pass オブジェクトは他のオブジェクトと同様にパージすることも可能です。
ただし、これらの機能があったとしても、 hit-for-pass オブジェクトがキャッシュに存在しない場合はリクエスト共有が発生し、同時に発生したリクエストに対して待ち時間が発生します。出来るだけ vcl_fetch
で Pass することは避けるようにして下さい。
req.hash_always_miss と req.hash_ignore_busy
req.hash_always_miss
を設定すると、リクエストがキャッシュに存在してもしなくても強制的に miss となります。vcl_recv
で Pass する場合とは、レスポンスがキャッシュされ、リクエストの共有が無効にならないという点で異なります。必要に応じて、後でリクエストを vcl_fetch
で Pass することも可能です。
2つ目の関連する変数に req.hash_ignore_busy
があります。これを true に設定すると、リクエスト共有が無効になり、各リクエストが個別にオリジンに送信されます。req.hash_ignore_busy
が true の場合もレスポンスはキャッシュ可能で、キャッシュはオリジンから受け取った最後のレスポンスで上書されます。キャッシュ後に発生したリクエストに返却されるオブジェクトは、最後に発生したキャッシュミスで取得したオブジェクトのコピーとなります。
req.hash_ignore_busy
は、主に複数の Varnish を利用した複雑な環境においてデッドロックを避ける目的で使用されます。
これらの両方の変数を利用することで、レスポンスをキャッシュしながら、強制的にリクエストを個別にオリジンに送信することが可能となります。
Back to Top