CloucdflareのTiered Cache(階層型キャッシュ)を有効にしてキャッシュヒット率を高めてみた

2022.05.26

CDNを活用する上では、キャッシュヒット率を高く保つことが大事です。 キャッシュヒット率が高くなるほど、オリジンへのアクセスが減り、オリジンの負荷やトラフィックを軽減できるからです。

キャッシュヒット率を高めるアプローチの一つが、キャッシュの階層化です。

今回は、Cloudflare CDNのTiered Cacheを用い、キャッシュを階層化してキャッシュヒット率を高める方法を紹介します。

キャッシュの階層化

Cloudflare の CDN は、デフォルトでは、キャッシュは各地のデータセンターで個別に管理され、キャッシュミス時には各DCがオリジンと通信します。 Tiered Cacheを用いると、 オリジンに最寄りのデータセンターをupper-tierとして選出し、このDCだけがオリジンと通信できるようにし、upper-tierと他のtlower-tierのDC間でキャッシュが階層化されます。

※ 図はIntroducing: Smarter Tiered Cache Topology Generation から引用

このようにキャッシュを階層化することで、lower-tier でキャッシュミスした時はupper-tierにコンテンツを問い合わせ、upper-tierにもキャッシュが存在しない場合のみ、オリジンに問い合わせます。 lower-tierの各DCが直接オリジンと通信しなくなるため、オリジンへのリクエストやオリジンとのトラフィックを抑制できます。

キャッシュの階層化を有効にするには、管理コンソールの Caching -> Tiered Cache から「Argo Tiered Cache」を有効にします。

やってみた

Tiered Cacheを利用する前・後のキャッシュ管理の違いを確認します。

AWS東京リージョンにあるオリジンに対して、AWS CloudShellを利用して、世界各地からアクセスしてみます。

Cloudflare Instant Logsで取得したHTTPリクエストログとオリジンのアクセスを突き合わせます。

主要フィールドの意味を確認します。

Field Value
CacheCacheStatus miss/hit/stale/dynamicなどのキャッシュステータス
CacheTieredFill リクエスト時にTiered Cacheのキャッシュが利用された場合はこのフラグが立つ
EdgeServerIP オリジンにリクエストをするエッジサーバーのIP。空の場合はオリジンへのリクエストが発生せず。
EdgeTimeToFirstByteMs ビューアーとCloudflareエッジ間のTTFB
OriginIP オリジンサーバーのIPアドレス
OriginResponseDurationMs Cloudflareエッジ-オリジン間のTTFB。オリジンへの接続からレスポンスを受け取るまでの時間
OriginResponseHeaderReceiveDurationMs オリジンサーバーの処理時間。オリジンへの接続後にレスポンスを受け取るまでの時間
UpperTierColoID Tiered Cacheで利用された upper tierのデータセンター

Tiered Cacheを利用しない場合

まずは、「Argo Tiered Cache」が OFF のデフォルトの挙動を確認します。

ヨーロッパから日本オリジンにアクセス

オリジンのある日本から遠く離れたドイツ・フランクフルトからアクセスします。

$ curl -s -D - https://example.com/test.json
HTTP/2 200 
date: Tue, 24 May 2022 09:29:27 GMT
content-type: application/json
content-length: 17
x-amzn-requestid: 355ca9c7-906b-44a1-bf7a-377cf8d5e3ed
x-amzn-trace-id: root=1-628ca577-0a0939734be100a414e41399;sampled=0
cf-cache-status: MISS
last-modified: Tue, 24 May 2022 09:29:27 GMT
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 710501c5185a90f2-FRA
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400

...

対応するCloudflareのリクエストログを抜粋します。

  • CacheCacheStatus : miss
  • CacheTieredFill : false
  • EdgeServerIP : 162.158.89.206
  • EdgeTimeToFirstByteMs : 1016 ms
  • OriginIP : 162.158.89.206
  • OriginResponseDurationMs : 954 ms
  • OriginResponseHeaderReceiveDurationMs : 256 ms
  • UpperTierColoID : 0

初回アクセスのためキャッシュミスし(レスポンスの cf-cache-status: MISSとリクエストログの CacheCacheStatus : miss)、オリジンにアクセスします。 ビューアーとCloudflareエッジ間のTTFB の EdgeTimeToFirstByteMs は 1016 ms でした。

オリジンサーバーの処理時間(OriginResponseHeaderReceiveDurationMs) は 256 ms と比較的短いのに対して、エッジからオリジンへの接続も含めた処理時間(OriginResponseDurationMs)は954msとはるかに大きな値になっています。 エッジ(ドイツ)とオリジン(日本)が遠く離れているのが原因です。

オリジンにリクエストしたソースIPは 162.158.89.206 でした。

これは、CloudflareのフランクフルトにあるのDCのIPアドレスです。

https://whatismyipaddress.com/ip/162.158.89.206

時間をおいて、もう一度アクセスすると、キャッシュヒットしました。

HTTP/2 200 
date: Tue, 24 May 2022 09:30:42 GMT
content-type: application/json
content-length: 17
x-amzn-requestid: 355ca9c7-906b-44a1-bf7a-377cf8d5e3ed
x-amzn-trace-id: root=1-628ca577-0a0939734be100a414e41399;sampled=0
cf-cache-status: HIT
age: 75
last-modified: Tue, 24 May 2022 09:29:27 GMT
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 7105039f2b7f9189-FRA
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
  • CacheCacheStatus : hit
  • CacheTieredFill : false
  • EdgeServerIP :
  • EdgeTimeToFirstByteMs : 57 ms
  • OriginIP :
  • OriginResponseDurationMs : 0 ms
  • OriginResponseHeaderReceiveDurationMs : 0 ms
  • UpperTierColoID : 0

エッジでキャッシュヒットしているため、ビューアーとCloudflareエッジ間のTTFB(EdgeTimeToFirstByteMs) は 1016 ms から 57 ms へと激減し、オリジンとの通信は発生しないため、関連するフィールドは 0/ブランク です。

ヨーロッパから日本オリジンにアクセス時の、キャッシュ状態別のHTTPレスポンスヘッダーとCloudflareリクエストログを整理します。

日本から日本オリジンにアクセス

続いて、オリジンと同じ東京からアクセスしてみましょう。

ヨーロッパ・日本それぞれ独自にキャッシュ管理され、オリジンへのリクエストも個別に発生します。

HTTP/2 200 
date: Tue, 24 May 2022 09:33:41 GMT
content-type: application/json
content-length: 17
x-amzn-requestid: 09b819c9-70f5-4d41-9eab-b0360b328572
x-amzn-trace-id: root=1-628ca675-0ae275e748757ef6028be0e9;sampled=0
cf-cache-status: MISS
last-modified: Tue, 24 May 2022 09:33:41 GMT
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 710507fdd8e9af30-NRT
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
  • CacheCacheStatus : hit
  • CacheTieredFill : false
  • ClientIP : 18.183.41.167
  • EdgeServerIP : 172.68.118.118
  • OriginIP : 54.65.184.103
  • EdgeTimeToFirstByteMs : 172 ms
  • OriginResponseDurationMs : 80 ms
  • OriginResponseHeaderReceiveDurationMs : 73 ms
  • UpperTierColoID : 0

初回アクセスのためキャッシュミスし、オリジンにアクセスします。 ビューアーとCloudflareエッジ間のTTFB(EdgeTimeToFirstByteMs) は 172 ms でした。

アクセス元とオリジンが至近距離にあるため、オリジンサーバーの処理時間(OriginResponseHeaderReceiveDurationMs : 73ms)とオリジンへの通信も含めた時間(OriginResponseDurationMs : 80ms)に大きな差はありません。

オリジンにリクエストしたソースIPは 172.68.118.118でした。 これは東京にあるCloudflareのDCのIPアドレスです。

https://whatismyipaddress.com/ip/172.68.118.118

もう一度アクセスすると、キャッシュヒットします。

HTTP/2 200 
date: Tue, 24 May 2022 09:35:24 GMT
content-type: application/json
content-length: 17
x-amzn-requestid: 09b819c9-70f5-4d41-9eab-b0360b328572
x-amzn-trace-id: root=1-628ca675-0ae275e748757ef6028be0e9;sampled=0
cf-cache-status: HIT
age: 103
last-modified: Tue, 24 May 2022 09:33:41 GMT
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 71050a8438993481-NRT
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
  • CacheCacheStatus : hit
  • CacheTieredFill : false
  • ClientIP : 18.183.41.167
  • EdgeServerIP :
  • OriginIP :
  • EdgeTimeToFirstByteMs : 22 ms
  • OriginResponseDurationMs : 0 ms
  • OriginResponseHeaderReceiveDurationMs : 0 ms
  • UpperTierColoID : 0

エッジでキャッシュヒットするため、EdgeTimeToFirstByteMs が 172 ms から 22 ms へと更に低下し、オリジンとの通信に関連するフィールドは 0/ブランク です。

Tiered Cacheを利用する場合

次にArgo Tiered Cacheを有効にし、トポロジーには「Smart Tiered Cache Topology」を選択します。

ヨーロッパから日本オリジンにアクセス

オリジンのある日本から遠く離れたドイツ・フランクフルトからアクセスします。

HTTP/2 200 
date: Tue, 24 May 2022 12:50:51 GMT
content-type: application/json
content-length: 18
x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e
x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0
last-modified: Tue, 24 May 2022 12:50:51 GMT
cf-cache-status: MISS
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 710628cf1ba09a1d-FRA
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
  • CacheCacheStatus : miss
  • CacheTieredFill : false
  • OriginIP : 52.198.171.117
  • EdgeServerIP : 172.70.123.15
  • EdgeTimeToFirstByteMs : 626 ms
  • OriginResponseDurationMs : 533 ms
  • OriginResponseHeaderReceiveDurationMs : 301 ms
  • UpperTierColoID : 382

初回アクセスのため、キャッシュミスし、オリジンへのアクセスが発生します。

オリジンにアクセスした IP(172.70.123.15) の所有者を確認すると、ビューアーそばのヨーロッパのものでなく、オリジン最寄りの東京にある Cloudflare データセンターのものです。

https://whatismyipaddress.com/ip/172.70.123.15

upper tier としてオリジン最寄りの東京のデータセンターが選出されていることがわかります。

Tiered Cache 利用時にオリジンと通信する upper tier データセンターを表す UpperTierColoID フィールドは、これまで 0 だったのに対して、今回は 382 が設定されています。

続けてアクセスすると、キャッシュヒットしました。

HTTP/2 200 
date: Tue, 24 May 2022 12:51:33 GMT
content-type: application/json
content-length: 18
x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e
x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0
last-modified: Tue, 24 May 2022 12:50:51 GMT
cf-cache-status: HIT
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 710629d25f7b9bbc-FRA
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400

cf-cache-status: HIT からキャッシュヒットしたことはわかりますが、age ヘッダーが存在しません。

Instant Logs を確認します。

  • CacheCacheStatus : hit
  • CacheTieredFill : true
  • OriginIP :
  • EdgeServerIP :
  • EdgeTimeToFirstByteMs : 470 ms
  • OriginResponseDurationMs : 219 ms
  • OriginResponseHeaderReceiveDurationMs : 0 ms
  • UpperTierColoID : 382

CacheCacheStatus : hit からキャッシュヒットしたことがわかり、CacheTieredFill : true から、エッジキャッシュミス後にオリジンの手前の upper tier がキャッシュを返したことがわかります。 ヨーロッパから日本への通信が発生しているため、 EdgeTimeToFirstByteMs が前回の 626 ms から 470 ms へとあまり改善していないのも納得です。

また、キャッシュに利用された UpperTierColoID が埋まっています。

もう一度リクエストします。

HTTP/2 200 
date: Tue, 24 May 2022 12:52:20 GMT
content-type: application/json
content-length: 18
x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e
x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0
last-modified: Tue, 24 May 2022 12:50:51 GMT
cf-cache-status: HIT
age: 89
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 71062af8fc656933-FRA
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400

今度は age ヘッダーもかえってきました。

  • CacheCacheStatus : hit
  • CacheTieredFill : false
  • OriginIP :
  • EdgeServerIP :
  • EdgeTimeToFirstByteMs : 28 ms
  • OriginResponseDurationMs : 0 ms
  • OriginResponseHeaderReceiveDurationMs : 0 ms
  • UpperTierColoID : 0

lower tier エッジがキャッシュを返しているため CacheTieredFill : falseUpperTierColoID : 0 となり、EdgeTimeToFirstByteMs は 470 ms から 28 ms へと激減しました。

ヨーロッパから日本オリジンにアクセス時の、キャッシュ状態別のHTTPレスポンスヘッダーとCloudflareリクエストログを整理します。

日本から日本オリジンにアクセス

続いて、オリジンと同じ東京からアクセスしてみましょう。

オリジンの前段に Upper Tier DCが待ち構えており、日本エリアから初めてリクエストしても、ドイツからのリクエスト時に作成されたキャッシュを利用できることを確認します。

HTTP/2 200 
date: Tue, 24 May 2022 12:53:09 GMT
content-type: application/json
content-length: 18
x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e
x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0
last-modified: Tue, 24 May 2022 12:50:51 GMT
cf-cache-status: HIT
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 71062c2afcb40b93-NRT
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400

Tiered Cacheの効果で、東京からのアクセスは初めてにもかかわらずキャッシュヒットしていますが、 age レスポンスヘッダーがありません。

  • CacheCacheStatus : hit
  • CacheTieredFill : true
  • OriginIP :
  • EdgeServerIP :
  • EdgeTimeToFirstByteMs : 339 ms
  • OriginResponseDurationMs : 3 ms
  • OriginResponseHeaderReceiveDurationMs : 0 ms
  • UpperTierColoID : 382

CacheCacheStatus : hitCacheTieredFill : trueUpperTierColoID : 382 から、 upper tier がキャッシュを返したことがわかります。 lower tierと upper tier が至近距離のためか、OriginResponseDurationMs はわずか 3 ms です。

もう一度アクセスします。

HTTP/2 200 
date: Tue, 24 May 2022 12:53:16 GMT
content-type: application/json
content-length: 18
x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e
x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0
cf-cache-status: HIT
age: 145
last-modified: Tue, 24 May 2022 12:50:51 GMT
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 71062c577c8620c5-NRT
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
  • CacheCacheStatus : hit
  • CacheTieredFill : false
  • OriginIP :
  • EdgeServerIP :
  • EdgeTimeToFirstByteMs : 29 ms
  • OriginResponseDurationMs : 0 ms
  • OriginResponseHeaderReceiveDurationMs : 0 ms
  • UpperTierColoID : 0

lower tier エッジがキャッシュを返しているため CacheTieredFill : falseUpperTierColoID : 0 となり、 EdgeTimeToFirstByteMs は 339 ms から 29 ms へと激減しました。

キャッシュ状態によるリクエストログ・レスポンスヘッダーの違い

レスポンスヘッダーの読み方

cf-cache-status age
[tiered cache]エッジでキャッシュヒット HIT 数字
[tiered cache]upper tierでキャッシュヒット HIT N/A
[tiered cache]キャッシュミスし MISS N/A
[非tiered cache]キャッシュミス MISS N/A

Cloudflare キャッシュログの読み方

Cloudflareのログの Tiered Cacheに関連するフィールドをキャッシュ状況に応じて整理します。

CacheCacheStatus CacheTieredFill EdgeServerIP EdgeTimeToFirstByteMs OriginResponseDurationMs OriginResponseHeaderReceiveDurationMs UpperTierColoID
[tiered cache]エッジでキャッシュヒット hit false ブランク 実測値 0 0 0
[tiered cache]upper tierでキャッシュヒットしエッジでキャッシュ化 hit true ブランク 実測値 0 0 upper tier ID
[tiered cache]キャッシュミスしupper tierでキャッシュ化 miss false upper tierのIP 実測値 実測値 実測値 upper tier ID
[非tiered cache]キャッシュミスしエッジでキャッシュ化 miss false エッジのIP 実測値 実測値 実測値 0

まとめ

CDNを効率的に使うには、キャッシュをヒットさせることが大事です。

そのようなアプローチの一つとして、Cloudflare Tiered Cache を紹介しました。 キャッシュを階層・集約化することでキャッシュヒット率が向上し、CDNとオリジン間の通信も減ります。

Tiered Cacheはあくまでも一時的なキャッシュのため、eviction/expireでキャッシュが削除されると、オリジンへのアクセスが発生します。 この欠点を補完し、キャッシュヒット率をさらに高めるソリューションとして、Cloudflare Cache Reserve というサービスがクローズド・ベータで提供されています。

Introducing Cache Reserve: massively extending Cloudflare’s cache

Cache Reserveを利用すると、キャッシュ化可能なコンテンツはオリジンから Cloudflare R2ストレージ(エッジ向けAmazon S3のようなもの)にプッシュされ、キャッシュミス時にはR2からコンテンツ配信されます。

キャッシュヒット率をさらに高め、R2はエグレス料金が無料のため、配信コストを抑えることが期待できます。

配信コンテンツによっては、R2のストレージコストを考慮しても、Cache Reserveが最適なソリューションとなります。

参考