[アップデート] Amazon CloudFront でキャッシュキーとオリジンリクエストポリシーによる管理が可能となりました

キャッシュ設定をポリシー化することでBehaviorごとの設定が非常に楽になりました!また、キャッシュキーとオリジンリクエストの設定が分離されたことで、キャッシュ効率に影響を与えることなくオリジンに追加情報を渡せるようになりました。
2020.07.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

4 連休ということもありアップデート記事が遅くなってしまいました。

先日のアップデートで、Amazon CloudFront でキャッシュキーとオリジンリクエストポリシーによる管理が可能となりました。

何がうれしいのか

キャッシュおよびオリジンリクエスト設定の外だし

これまで Behavior の設定ごとに Cache Based on Selected Request Headers の設定をしていたかと思いますが、「ポリシー設定」として外だしされたことで、同じような内容を何度も設定する必要がなくなりました。

共通利用できるキャッシュキー、オリジンリクエストをポリシーとして作成します。各 Behavior では事前作成済みのポリシーをプルダウンメニューで選択するだけで設定できるようになりました。

キャッシュキーとオリジンリクエストの分離

これまで HTTP ヘッダー、クエリ文字列、cookie をオリジンに転送した場合、それらの各パラメータの組み合わせがキャッシュキーに設定されていました。つまり 転送した情報=キャッシュキー が従来の設定となります。

キャッシュはすべてのキャッシュキーの値が一致する場合のみ、同一オブジェクトと判断されキャッシュフロントからレスポンスを返します。オリジンへ転送する情報が増えるほど、そのキャッシュに適合するビューワーリクエストは限定的になりキャッシュ効率が低下します。キャッシュ効率の低下はレスポンス速度の低下とオリジンサーバーの負荷増を引き起こします。

今回のアップデートによりキャッシュキーとオリジンリクエストを分離して設定できます。例えばログ分析や、特定の情報に基づいて処理を分岐させるなど、何らかの理由によりオリジンリクエストに HTTP ヘッダーを転送したい場合でも、キャッシュに影響を与えることなく設定できるようになりました。

注意点

  • キャッシュポリシーに設定されたキャッシュキーはオリジンリクエストに含まれます
  • オリジンリクエストポリシーを設定する場合は、キャッシュポリシーの設定が必要です
  • オリジンリクエストポリシーはキャッシュミス時にオリジンリクエストに含める情報を指定するものです。

やってみる

今回は User-Agent をオリジンリクエストに含める場合の動作を、従来の設定方法と、今回のアップデート設定とで比較してみていきます。

従来の設定(HTTP ヘッダー転送なし)

最初は Cache Based on Selected Request Headers で Whitelist を設定していないパターンです。従来の設定は Use legacy cache settings を選択することで利用可能です。既存のディストリビューションは Use legacy cache settings に設定されていますので、今回のアップデートによって動作が勝手に変わることはありません。

同一の URL パスを指定する場合、すべてのリクエストは同一オブジェクトとしてキャッシュフロントからレスポンスが返ります。

$ curl -I  http://d25co97t8bd3jk.cloudfront.net
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 19
Connection: keep-alive
Date: Sat, 25 Jul 2020 12:18:46 GMT
Server: Apache/2.4.43 ()
Last-Modified: Sat, 25 Jul 2020 03:05:32 GMT
ETag: "13-5ab3b5ccf5a48"
Accept-Ranges: bytes
X-Cache: Miss from cloudfront
Via: 1.1 fa445778cee6132350999e6439a60aa6.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT51-C2
X-Amz-Cf-Id: eDXerbao9z7gI6jycMjwCxCR6XRm914byLnU52CjC6kUxe_BL1oaIA==

$ curl -I -A "hoge" http://d25co97t8bd3jk.cloudfront.net
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 19
Connection: keep-alive
Date: Sat, 25 Jul 2020 12:18:46 GMT
Server: Apache/2.4.43 ()
Last-Modified: Sat, 25 Jul 2020 03:05:32 GMT
ETag: "13-5ab3b5ccf5a48"
Accept-Ranges: bytes
X-Cache: Hit from cloudfront
Via: 1.1 847d1973b053f95bdc0e53820c660644.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT51-C2
X-Amz-Cf-Id: GrA4-xMXaCxowJ8IjBVt5DNXApAJEAnO2nPzgP6nrdtXybyiXR1bMg==
Age: 282

Cache Based on Selected Request Headers はデフォルトのままですので、User-Agent はキャッシュキーとして機能していません。

また CloudFront では User-Agent をオリジンリクエストに含めていない場合、オリジンに届く User-AgentAmazon CloudFront に置換されます。よって、本来の User-Agent をオリジン側で利用できないことが判ります。

64.252.110.131 - - [25/Jul/2020:12:18:46 +0000] "HEAD /index.html HTTP/1.1" 200 - "-" "Amazon CloudFront"

2回目のリクエストはキャッシュフロントから返っているので、オリジンの access_log には初回リクエスト分のログのみ表示されています。

従来の設定(HTTP ヘッダー転送あり)

次に Cache Based on Selected Request HeadersUser-Agent を設定したパターンです。

一旦、CloudFront からは Invalidation でキャッシュを削除しています。

$ curl -I  http://d25co97t8bd3jk.cloudfront.net
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 19
Connection: keep-alive
Date: Sat, 25 Jul 2020 12:50:31 GMT
Server: Apache/2.4.43 ()
Last-Modified: Sat, 25 Jul 2020 03:05:32 GMT
ETag: "13-5ab3b5ccf5a48"
Accept-Ranges: bytes
X-Cache: Miss from cloudfront
Via: 1.1 ea2a9baea9a4e4c428c28f3df16ed292.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT51-C2
X-Amz-Cf-Id: 3PdsUrxvGPm2bGeR5sZl7P5Grp29Jbf2fU7YvCQ3sQh-2zwvo4atlA==

$ curl -I -A "hoge" http://d25co97t8bd3jk.cloudfront.net
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 19
Connection: keep-alive
Date: Sat, 25 Jul 2020 12:50:38 GMT
Server: Apache/2.4.43 ()
Last-Modified: Sat, 25 Jul 2020 03:05:32 GMT
ETag: "13-5ab3b5ccf5a48"
Accept-Ranges: bytes
X-Cache: Miss from cloudfront
Via: 1.1 8d60cea7dda499ce29d23f5fe409aac9.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT51-C2
X-Amz-Cf-Id: QXR5KBh08HeACVdla3otNvY6jI7fmmEjw_D4FzrL_IhiO4rW3peqtg==

従来の設定ではオリジンに転送設定された HTTP ヘッダー、クエリ文字列、Cookie は、キャッシュキーとして機能しますので User-Agent: hoge-A "hoge")は初回のオブジェクトと異なるものとして判断されます。そのため、先程とは異なり、hoge のリクエストが X-Cache: Miss from cloudfront となっています

いずれもキャッシュミスになりましたのでオリジンへとリクエストが転送されています。よってログは二行出力されています。また、User-Agentをオリジンリクエストに含めた場合は、Amazon CloudFront に置換されることなく、本来の User-Agentが表示されていることが判ります。

64.252.110.131 - - [25/Jul/2020:12:50:31 +0000] "HEAD /index.html HTTP/1.1" 200 - "-" "curl/7.64.1"
13.113.203.106 - - [25/Jul/2020:12:50:38 +0000] "HEAD /index.html HTTP/1.1" 200 - "-" "hoge"

このようにオリジン側で本来の User-Agent を取得する場合、キャッシュキーとして判断されます。そのため、著しいキャッシュ効率の低下へとつながることから CloudFront では非推奨とされていました。

キャッシュポリシーとオリジンリクエストポリシーによる設定

それでは、今回のアップデートとなるキャッシュポリシーおよびオリジンリクエストポリシーを使用してみましょう。

キャッシュポリシーはマネージドポリシーの Managed-CachingOptimized を使用します。特にキャッシュキーとしての設定はありません(デフォルトのドメイン名と URL パスのみ)。その他にもよく利用されるキャッシュポリシーおよび、オリジンリクエストポリシーはマネージドポリシーとして提供されています。詳細はリンクより公式ドキュメントをご確認ください。

オリジンリクエストポリシーは Create origin request policyWhitelistUser-Agent を設定したものを作成しています。

これらを Behavior で設定します。各ポリシーを使用する場合は、Cache and origin request settingsUse a cache policy and origin request policy を選択し、Cache Policy, Origin Request Policy でそれぞれのポリシーを設定します。

$ curl -I  http://d25co97t8bd3jk.cloudfront.net
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 19
Connection: keep-alive
Date: Sat, 25 Jul 2020 13:21:32 GMT
Server: Apache/2.4.43 ()
Last-Modified: Sat, 25 Jul 2020 03:05:32 GMT
ETag: "13-5ab3b5ccf5a48"
Accept-Ranges: bytes
X-Cache: Miss from cloudfront
Via: 1.1 674ee281632f4185bb0fdbd22348ce61.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT51-C2
X-Amz-Cf-Id: BqNxQyE9yjIJIXREjlaDyLBRr0yQc79uTB9Ywh-bG_F0IlvNM_o9YQ==

$ curl -I -A "hoge" http://d25co97t8bd3jk.cloudfront.net
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 19
Connection: keep-alive
Date: Sat, 25 Jul 2020 13:21:32 GMT
Server: Apache/2.4.43 ()
Last-Modified: Sat, 25 Jul 2020 03:05:32 GMT
ETag: "13-5ab3b5ccf5a48"
Accept-Ranges: bytes
X-Cache: Hit from cloudfront
Via: 1.1 f0b8008589ca3639012e9961b8704ac9.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT51-C2
X-Amz-Cf-Id: g2tLXkC_OPpuVqB8vj1wRomEicooWwEfqcTjDoAKx2RFrM3FbXRdtg==
Age: 14

キャッシュポリシーに User-Agent は含まれていないため、X-Cache: Hit from cloudfront が返っています。つまり、2 つのリクエストは同一オブジェクトとして処理されています。

一方でオリジン側のログを確認すると、User-Agent には本来の curl/7.64.1 が表示されていることから、User-Agent はオリジンに転送されていることが判ります。また 2 回目のリクエストはキャッシュフロントが返しているため、ログが一行のみ表示されています。

64.252.110.131 - - [25/Jul/2020:13:21:32 +0000] "HEAD /index.html HTTP/1.1" 200 - "-" "curl/7.64.1"

以上のことから従来の オリジンへの転送=キャッシュキー の構成とは異なり、キャッシュキー、オリジンリクエストのそれぞれで HTTP ヘッダーに対する扱いを設定できていることが解りました。

また、冒頭に述べたとおりオリジンリクエストはキャッシュミス時に対する設定です。オリジンリクエストポリシーを設定したからといって、キャッシュヒット/ミスに関係なく常時オリジンリクエストに含めるためのものではありません。

さいごに

ポリシー設定が外だしされたことで、これまで同じようなポリシー設定を各 Behavior で何度も設定していた煩わしさが解消されました。

また、キャッシュキーとオリジンリクエストの分離については、まだ使いどころがピンと来ていませんが、キャシュ効率に影響することなく、オリジンに渡したい HTTP ヘッダー、クエリ文字列、cookie を制御できる(といってもキャッシュミス時のみですが)という点で、これまでより柔軟な設定が可能になったことは間違いないですね。

以上!大阪オフィスの丸毛(@marumo1981)でした!