Ttlに関する問題のよくある原因


#1

この記事の内容について

この記事ではFastlyを利用した際にオブジェクトが思った通りキャッシュされない場合のよくある原因と確認すべき内容について説明します。

オブジェクトに設定されているTTLを確認する手順については以下のサイトを参照して下さい。

特に記載がない限り本記事の記載内容はデフォルト設定での挙動となります。
Fastlyの正式なサポート情報は "https://docs.fastly.com/" を参照して下さい。

キャッシュを行わない条件

Fastlyサーバーでは以下の条件の場合はキャッシュを行いません。

  • HTTPリクエストのMethodがGETかHEAD以外の場合(例POST, PUT, DELETEなど)
  • オリジンからのHTTPレスポンスにSet-Cookieが含まれている。
  • オリジンからのレスポンスにCache-Control: private が含まれている
    (Cache-Control: no-store, no-cache はキャッシュ対象となります)

まずはキャッシュされないリクエストが上記の条件に合致していないかを確認しましょう。

Varyヘッダー

Cacheに影響を与えるヘッダーとしてはVaryヘッダーがあります。Varyヘッダーとは簡単にいうとFastlyサーバーなどのサーバーに「同じURLでもVaryヘッダーに指定されているヘッダーの内容が異なれば別オブジェクトとして取り扱いなさい」というオリジンサーバーからの命令となります。

VaryがあってもFastlyサーバーにキャッシュ自体は行われますが、例えばオリジンからのレスポンスにVary: User-Agentというヘッダーが含まれる場合ChromeやFireFox、同じChromeであってもバージョンが違えば異なるオブジェクトとしてキャッシュされます。

そのためキャッシュ効率が非常に悪くなり、結果としてキャッシュヒット率の低下、オリジンオフロード率の低下とCDNサービスを適用するメリットが低下してしまいます。

一般的にVaryにAccept-Encodingのみが指定されている場合は問題になることは少ないですが、それ以外のヘッダーがVaryに指定されている場合はキャッシュが効率的に行えていない可能性が高いです。

特にWordPressやDrupalなどをCMSとして利用している場合、無条件でVaryにCookieなどが含まれている場合があるので注意が必要です。

オリジン側で本当に必要なヘッダー情報のみをVaryに指定するか、Fastlyサーバー側でVaryヘッダーの内容を無視するような設定を追加するなどの対処を検討しましょう。

VaryヘッダーがFastlyサーバー上の挙動に及ぼす影響については英文になってしまいますが


のサイトに詳しく記載されています。

FastlyサーバーのTTLの選択ロジック

Fastlyサーバーはオリジンサーバーからのレスポンスに含まれるCache-Controlヘッダーなどの値の内容に基づいてキャッシュするオブジェクトに設定するTTLを決定します。

TTLの設定に関連するヘッダーは何種類かあるのですが、以下の様な優先順位で適用するTTLが決定します。

  1. Set-CookieまたはCache-Control: privateを含む場合 → キャッシュしない
  2. Surrogate-Control: max-age=ヘッダーに指定したTTL
  3. Cache-Control: s-maxage=ヘッダーに指定したTTL
  4. Cache-Control: max-age=ヘッダーに指定したTTL
  5. Expires:ヘッダーに指定したTTL
  6. Fastly設定上で指定されたFallback TTL(Default TTL)

つまりSet-CookieCache-Control: privateが存在する場合はSurrogate-ControlやExpiresヘッダーが存在していてもキャッシュが行われません。

Surrogate-Control:max-age=120Cache-Control: max-age=60のふたつのヘッダーが存在する場合はSurrogate-Controlヘッダーが優先されますので、TTLとしては120秒が適用されることになります。

意図しないTTLが適用されている場合は上記の優先順位も確認して下さい。

クエリストリングやSSLリクエストのキャッシュについて

Fastlyサーバーはデフォルトの設定ではリクエストされたHostとPathとクエリストリングをキャッシュされたオブジェクトを判断するための情報として利用します。

つまり以下のURLでいうと太字の部分がキャッシュを識別するキーとなります。
http://www.sample.com/aaa.html?id=111
http://www.sample.com/aaa.html?id=222

そのため上記のURLはそれぞれ別のページとしてキャッシュされます。

またキャッシュを行う際にSSLとNon−SSLは考慮されません。そのため以下のURLは同じオブジェクトとして扱われます。
http://www.sample.com/aaa.html?id=111
https://www.sample.com/aaa.html?id=111

SSLとNon-SSLで返却されるオブジェクト内容が異なる場合、SSLかどうかを示すヘッダーをVaryに設定することで問題を回避することが出来ます。

Varyにヘッダーを追加する手順は以下のページをご確認下さい。
https://docs.fastly.com/guides/vcl/manipulating-the-cache-key

404レスポンスなどの取り扱い

Fastlyは404 Not Found レスポンスも指定されたTTLの期間キャッシュを行います。
Fastlyがデフォルトでキャッシュを行うHTTPのレスポンスコードは以下の通りです。

| Code | Message |
|200 |OK|
|203 |Non-Authoritative Information|
|300 |Multiple Choices|
|301 |Moved Permanently|
|302 |Moved Temporarily|
|404 |Not Found|
|410 |Gone|

404レスポンスなど、特定のレスポンスコードの場合に通常とは異なるTTLを設定する手順は以下のページをご確認下さい。
https://docs.fastly.com/guides/basic-configuration/overriding-caching-defaults-based-on-backend-responses


以上がキャッシュされているはずのオブジェクトがキャッシュされていない場合のよくある原因です。

もちろんここで説明した以外のものが原因でキャッシュが正常に行われていないケースもありますが、思っている通りキャッシュされていないように思えるときはまずはこれらの内容を確認して見てください。