ただ、見てわかるようにほぼ静的なコンテンツのサイトなので、アクセス毎にアプリケーションサーバを走らせる意味がない。また、このVPSの一番安いコースにおいているので、あまり贅沢に資源を使いたくない。と言ったことから生成したhtmlをキャッシュして2度目のアクセスからはアプリケーションサーバやデータベースにアクセスしないようにしている。
Webシステムによっては、アプリケーションサーバで静的なhtmlファイルを作成し負荷の軽減をしたりするが、キャッシュファイルを自前で扱うのはvalidation等色々だるいので、このブログシステムではnginxに任せている。
今回はその設定の紹介
基本的にnginxは設定が簡単なので超オススメ。キャッシュの設定はたったこれだけ。全体の設定ファイルはこっちに置いとく。
http {
proxy_cache_path /usr/local/nginx/cache levels=1:2 keys_zone=cache-space:4m max_size=50m inactive=120m;
proxy_temp_path /usr/local/nginx/tmp;
server {
location / {
proxy_cache cache-space;
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 20m;
}
}
}
簡単に説明すると、まず、最初のproxy_cache_pathとproxy_temp_pathでキャッシュが格納されるディレクトリとサイズ等を指定する。詳しくはこの辺を見た方が早いが、この設定では、キャッシュ用に、メモリを4M使う、ディスクの最大サイズは50M、120分間アクセスがないキャッシュファイルは削除、の意味。
localtion / 内で、実際にどういうものをキャッシュするか決める。proxy_cache_valid には、httpのレスポンスコードと、そのレスポンスコードを返したときのコンテンツをどのくらいの時間キャッシュするかを書く。
この場合、正常処理である200または302を返した場合、そのコンテンツをnginxが60分間保持し、その後60分間、同じURLでアクセスがあった場合、アプリケーションサーバ(ここの場合はSinatra)に問い合わせずキャッシュをそのまま返す。
追記1:
Twitterにて: 「なぜ404は20分にしているのか」というのがあったが、正直なところあまり深い意味はないが、設定したときは以下のことを考えていた。
- 404を返すだけなら、アプリケーションサーバの負荷はたいしたことなさそう。
- 404はエラーなので(相手側のエラーの場合と、実際にファイルがない場合)、何か直す必要がある場合にはすぐ反映されるように。
追記2:
Twitterにて: 「データ更新をしても最大60分間は実際の更新が行われないということか」というのがあった、そのままだとそうなる。でも自分は更新時の処理でCacheをクリアしている。ただし、NginxにはCacheを消すという正式な方法がまだ用意されていないのでアンオフィシャルな方法である「単純にcacheディレクトリの下のファイルをすべて消す」というので運用している(cacheディレクトリの下のディレクトリは消してはダメ)。今のところそれで問題は起きてない。追記: 部分的にcacheをpurgeする方法を書いた。
abを使って簡単なベンチマークを取ってみた
nginxのキャッシュなしの場合:
% ab -n 100 -c 20 http://blog.madoro.org/mn/14
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking blog.madoro.org (be patient).....done
Server Software: nginx/0.8.31
Server Hostname: blog.madoro.org
Server Port: 80
Document Path: /mn/14
Document Length: 5844 bytes
Concurrency Level: 20
Time taken for tests: 9.049 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 605444 bytes
HTML transferred: 588577 bytes
Requests per second: 11.05 [#/sec] (mean)
Time per request: 1809.781 [ms] (mean)
Time per request: 90.489 [ms] (mean, across all concurrent requests)
Transfer rate: 65.34 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 161 174 9.2 173 202
Processing: 450 1522 301.2 1456 2268
Waiting: 224 1090 286.8 1059 1893
Total: 613 1696 306.1 1620 2454
Percentage of the requests served within a certain time (ms)
50% 1620
66% 1789
75% 1808
80% 1822
90% 1853
95% 2439
98% 2449
99% 2454
100% 2454 (longest request)
nginxのキャッシュありの場合
% ab -n 100 -c 20 http://blog.madoro.org/mn/14
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking blog.madoro.org (be patient).....done
Server Software: nginx/0.8.31
Server Hostname: blog.madoro.org
Server Port: 80
Document Path: /mn/14
Document Length: 5844 bytes
Concurrency Level: 20
Time taken for tests: 3.236 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 656124 bytes
HTML transferred: 636251 bytes
Requests per second: 30.90 [#/sec] (mean)
Time per request: 647.157 [ms] (mean)
Time per request: 32.358 [ms] (mean, across all concurrent requests)
Transfer rate: 198.02 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 162 177 10.1 174 201
Processing: 329 389 74.3 351 791
Waiting: 164 176 16.7 167 234
Total: 494 566 75.5 527 957
Percentage of the requests served within a certain time (ms)
50% 527
66% 599
75% 617
80% 628
90% 652
95% 667
98% 817
99% 957
100% 957 (longest request)
格段にレスポンスがよくなっているのがわかる。
このような並列のアクセスだけなく、単体のアクセスのレスポンスも早くなるので、負荷が高いサイトだけでなく(ここのような)零細なサイトでも恩恵を得ることができる。最近のコンテンツは動的な部分にJavascriptを使うことが多くなっているので、このようなキャッシュがしやすくてよい。
記事の内容についての質問、苦情、間違いの指摘等なんでもtwitterでどうぞ。 Tweet