Carpe Diem

備忘録。https://github.com/jun06t

CloudFrontのキャッシュでハマった話

概要

ブラウザのキャッシュ - Carpe Diem
を検証している時に期待した挙動をしなくてハマったので、CloudFrontのキャッシュの動作と注意点をまとめます。

CloudFrontのキャッシュ動作

レスポンスヘッダのx-cacheを見ると以下の3つに区別できます。

x-cache CloudFrontのキャッシュ Originへのリクエス Originのレスポンス
Miss from cloudfront なし
or
あるがTTL切れでOriginに更新あり
あり 200でリソース返す
Hit from cloudfront あり なし なし
RefreshHit from cloudfront あるがTTL切れ あり 304でリソースは返さない

この中で注意なのはRefreshHit from cloudfrontです

注意点

RefreshHitはヘッダーを更新しない

Originのレスポンスをみると分かりますが、ETagのチェックで304を返しておりCloudFront上のキャッシュに変更はないため、キャッシュの持つヘッダー情報は更新されません
そうすると

  • Originのコンテンツに新しいヘッダーを付けても反映されない(cache-controlなど)
  • Expiresの日付が更新されない

といったことが起きます。そのため ブラウザのキャッシュ - Carpe Diem で説明したブラウザキャッシュがうまく働きません。

MinTTL、MaxTTL、DefaultTTLをすべて0にしてもRefreshHitになる

CFのキャッシュを避ける方法の1つに「MinTTL、MaxTTL、DefaultTTLをすべて0する」と言うものがあります。
しかしながらこれは実のところキャッシュされており、TTLが切れてるから必ずOriginにリクエストするのであって、Originに変更がなければCFのキャッシュを使うためRefreshHitになります。

そのため先程と同じ問題が起きます。

対処方法

主に以下の4つがあります。

  • コンテンツを更新する(ただしETagはファイルのハッシュ値を見るので、作成日が違うだけの同一ファイルは更新されない)
  • クエリパラメータを付けてキャッシュを回避する
  • Invalidationでキャッシュを消す
  • OriginでCache-Control: no-storeを付ける(ただしキャッシュされる前に)

これらにすればMiss from cloudfrontに変わり、期待する挙動になると思います。

まとめ

CloudFrontを挟む時はキャッシュの挙動を理解していないと無駄な時間を過ごすことになるので気をつけましょう。

ソース