概要
ブラウザのキャッシュ - 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を挟む時はキャッシュの挙動を理解していないと無駄な時間を過ごすことになるので気をつけましょう。