【この記事の概要】
前回⇒
CloudFlareでキャッシュ可否の条件は「URLの末尾がキャッシュ対象拡張子に見えること」だった
CloudFlareのキャッシュレベルは Basic / Simplified / Aggressive の3段階から選べますが、その違いがイマイチ解らなかったので調べました。
3段階のキャッシュレベルの違いは?
CloudFlareの「パフォーマンス設定」画面では、Caching Levelを下記3段階に設定できるとあります。
- Aggressive: http://cloudflare.example.jp/pic.jpg?with=query
- Simplified: http://cloudflare.example.jp/pic.jpg
?ignore=this-query-string
- Basic: http://cloudflare.example.jp/pic.jpg
言わんとすることはだいたい分かるんですが、具体的な挙動を見てみました。
| Basic | Simplified | Aggressive |
(1) test.js | ○される | ○される | ○される |
(2) js.cgi?q=.js | ○される | ○される | ○される |
(3) test.html | ×されない | ×されない | ×されない |
(4) js.cgi?1=.js&2=query | ×されない | ×されない | ×されない |
(5) test.js?with=query | ×されない | △されるけど※1 | ○されるけど※2 |
(1)や(2)のように、URLがキャッシュ対象拡張子で終わっている(ようにみえる)なら、3レベルともキャッシュされます。
(3)(4)のように、URLが「キャッシュ対象拡張子」で終わっていない場合は、3レベルともキャッシュされません。
レベル設定で挙動が変わるのは、
(5)のような「キャッシュ対象拡張子で、クエリ文字列がある場合」です。
(※1) Simplifiedではクエリ文字列は削られるけど……?
キャッシュレベルがSimplifiedで、上記表の(5)のパターン、つまり「キャッシュ対象拡張子・クエリ文字列あり」の場合、次のような挙動になります。
- エッジサーバーからオリジンサーバーへは、クエリ文字列を取り除いてリクエストが送られる
- ただしキャッシュ内容はクエリ文字列付きのURLごとにそれぞれ保持される
ユーザー | file.js?with=query
→①→
←④←
file.js?with=query | CloudFlare
エッジ
サーバー | file.js
→②→
←③←
file.js | オリジン
サーバー |
挙動Aは文字どおりですが、Bがちょっと理解しにくいので、具体例で見てみます。
次のような、日時とURIをJavaScriptで出力するCGIスクリプトを用意しました。
#/usr/bin/ruby
puts "Content-type:application/javascript"
puts
puts "document.writeln('#{Time.now.to_s}');"
puts "document.writeln('#{ENV['REQUEST_URI']}');"
このCGIスクリプトに、js.cgi/pathinfo.js?with=query という形でアクセスしてみます。
$ curl -i 'http://cloudflare.example.jp/js.cgi/pathinfo.js?with=query'
HTTP/1.1 200 OK
CF-Cache-Status: MISS
document.writeln('Mon Mar 04 00:30:00 +0900 2013');
document.writeln('/js.cgi/pathinfo.js');
$ curl -i 'http://cloudflare.example.jp/js.cgi/pathinfo.js?with=query'
HTTP/1.1 200 OK
CF-Cache-Status: HIT
document.writeln('Mon Mar 04 00:30:00 +0900 2013');
document.writeln('/js.cgi/pathinfo.js');
1回目のアクセスでキャッシュが作られ、2回目のアクセスではそのキャッシュが返ってきています。
ENV['REQUEST_URI'] が「pathinfo.js」で終わっていて、「?with=query」が付いていません。クエリ文字列はエッジサーバーが切り落としたようです。
ここで、クエリ文字列を変えてアクセスしてみます。
$ curl -i 'http://cloudflare.example.jp/js.cgi/pathinfo.js?with=query2'
HTTP/1.1 200 OK
CF-Cache-Status: MISS
document.writeln('Mon Mar 04 00:32:22 +0900 2013');
document.writeln('/js.cgi/pathinfo.js');
$ curl -i 'http://cloudflare.example.jp/js.cgi/pathinfo.js?with=query2'
HTTP/1.1 200 OK
CF-Cache-Status: HIT
document.writeln('Mon Mar 04 00:32:22 +0900 2013');
document.writeln('/js.cgi/pathinfo.js');
さっきとは別のキャッシュがエッジサーバーに作られました。(Time.nowの出力する日時もさっきと違います)
しかし ENV['REQUEST_URI'] はこちらもさっきと同じ「/js.cgi/pathinfo.js」です。
というわけで、オリジンサーバーに対してはクエリ文字列を削った状態でアクセスしにくるけど、キャッシュはそれぞれ作成されるというよく分からない挙動です。
どうせクエリ文字列を切り落とすなら、キャッシュも共有してくれたほうが嬉しかったかも。
ちなみに、表の(2)のケースではクエリ文字列は削られずにオリジンサーバーに渡ります。
$ curl -i 'http://cloudflare.example.jp/js.cgi?q=.js'
HTTP/1.1 200 OK
CF-Cache-Status: MISS
document.writeln('Mon Mar 04 00:35:00 +0900 2013');
document.writeln('/js.cgi?q=.js');
(※2) Aggressiveでクエリ文字列がある場合、すぐにはキャッシュは作られない?
続いてキャッシュレベルがAggressiveで、キャッシュ対象拡張子・クエリ文字列ありの場合。
次のような挙動になります。
- 同一URL(同一クエリ文字列)に複数回アクセスがあっても、すぐにはキャッシュを作らない
- 何回かアクセスがあったらキャッシュを作り、以降のアクセスはキャッシュを返す
$ curl -i 'http://cloudflare.example.jp/js.cgi/pathinfo.js?with=query'
HTTP/1.1 200 OK
CF-Cache-Status: MISS
document.writeln('Mon Mar 04 00:40:00 +0900 2013');
document.writeln('/js.cgi/pathinfo.js?with=query');
$ curl -i 'http://cloudflare.example.jp/js.cgi/pathinfo.js?with=query'
HTTP/1.1 200 OK
CF-Cache-Status: MISS
document.writeln('Mon Mar 04 00:40:11 +0900 2013');
document.writeln('/js.cgi/pathinfo.js?with=query');
$ curl -i 'http://cloudflare.example.jp/js.cgi/pathinfo.js?with=query'
HTTP/1.1 200 OK
CF-Cache-Status: MISS
document.writeln('Mon Mar 04 00:40:22 +0900 2013');
document.writeln('/js.cgi/pathinfo.js?with=query');
$ curl -i 'http://cloudflare.example.jp/js.cgi/pathinfo.js?with=query'
HTTP/1.1 200 OK
CF-Cache-Status: HIT
document.writeln('Mon Mar 04 00:40:22 +0900 2013');
document.writeln('/js.cgi/pathinfo.js?with=query');
最初の3回はオリジンサーバーにアクセスが行っていますが、4回めでキャッシュが返ってきました。
キャッシュを作る条件が「同一クエリで(一定期間中に?)3回アクセスがあったら」なのかどうかは不明ですが、
いきなりキャッシュが作られて使われるわけではないのは要注意。
たぶん検索フォームなどで「よく検索されるワードの検索結果はキャッシュして、あまり検索されないワードの検索結果は(ロングテールになってエッジサーバーの
キャッシュヒット率が悪そうなので)キャッシュしない」という使われ方を想定しているんじゃないかと。
次回:キャッシュレベル設定では選べない特殊メニュー「Cache everything」
この記事では3種類のキャッシュレベルの挙動の違いを見ましたが、実は「パフォーマンス設定」の画面からは選べない第4の選択肢が存在するのです。それが「
Cache everything」。
次の記事では、この「Cache everything」の挙動を確認します。