ウェブサーバーのキャッシュ機能は、動的なページの高速化にかなり役立ちます。
例えば、Wordpressなどは覿面(てきめん)です。キャッシュ機能の有無で、体感する表示速度は10倍以上になることがあります。(もちろんキャッシュされている場合です)
そのキャッシュ機能で有名なウェブサーバーの一つがNginxです。(Squidやvarnish などキャッシュエンジンと呼ばれるキャッシュに特化した有名なサーバーもありますが、ここではウェブサーバーの機能も併せ持つという意味で書いています。)
Nginxのキャッシュ機能には、大きく2つあります。
- proxy cache
Nginxがバックエンドのサーバーに処理を渡した結果をキャッシュする機能です。
- fastcgi cache
NginxのFastCGIのレスポンスを直接キャッシュする機能です。
Nginx をリバースプロキシ(キャッシュ) として使ってみた で解説した リバースプロキシの設定例は、proxy cache に相当します。
このリバースプロキシにおけるキャッシュ(proxy cache)を簡単に解説するには、以下のような図が参考になるかと思います。
- キャッシュを使わない :
- → Nginx(Proxy) → Nginx(Web) → FastCGI(PHP etc)
要求されたページが、キャッシュ非対象か、あるいはキャッシュにない場合は、上記の経路で動的なページを作成します。
もちろん、ここでのNginx(Web)は、Apache(Web)でもOKですし、FastCGI(PHP etc)は、PHPモジュールなどでも良いです。
あくまで、以下のようにウェブサーバーからの戻りをキャッシュ保存するため、ウェブサーバー以降が何であるのかは問われません。
- ← Nginx(Proxy) ← Cache ← Nginx(Web) ← FastCGI(PHP etc)
先にも書いたように、ここでもポイントは、ウェブサーバーからのレスポンスをキャッシュする点です。
- → Nginx(Proxy) → Nginx(Web) → FastCGI(PHP etc)
- キャッシュを返信する :
要求されたページが、キャッシュにある場合は、そのキャッシュ内容をそのまま返信します。
また、先のproxy cache に対してfastcgi cacheを簡単に解説するには、以下のような図が参考になるかと思います。
- キャッシュを使わない :
- → Nginx(Proxy) → Nginx(Web) → FastCGI(PHP etc)
要求されたページが、キャッシュ非対象か、あるいはキャッシュにない場合は、上記の経路で動的なページを作成します。
先のproxy cache との違いは、プロキシサーバーが存在しないことです。
このfastcgi cacheでは、もちろん、ウェブサーバーは、Nginx(Web)でなければなりませんし、FastCGI(PHP etc)は、FastCGI以外にありません。
- ← Nginx(Proxy) ← Nginx(Web) ← Cache ← FastCGI(PHP etc)
ここでもポイントは、FastCGIからのレスポンスをキャッシュする点です。
- → Nginx(Proxy) → Nginx(Web) → FastCGI(PHP etc)
- キャッシュを返信する :
要求されたページが、キャッシュにある場合は、そのキャッシュ内容をそのまま返信します。
上記のとおりプロキシサーバーの機能が、すっぽり無くなったのが、fastcgi cacheになります。
proxy cacheでは、図のようにサーバーの分散化を容易に図れるような仕組みになっています。
逆にfastcgi cacheでは、サーバーの分散化というより動的ページのキャッシュがメインの仕組みになっています。
Nginx をリバースプロキシ(キャッシュ) として使ってみた の例では、1台のサーバーでリバースプロキシを実現しました。
これは、サーバーの分散化を図ったものでなく、キャッシュをメインに行うための構成です。
そのキャッシュだけを考えると、fastcgi cacheが如何に効率的かは、上図でも簡単に示せていると思います。
今回は、そのキャッシュ機能が効率的なfastcgi cacheを Nginxでのリバースプロキシの設定例 と同じように 解説してみます。
nginx でリバースプロキシ、FastCGIキャッシュのキャッシュを削除する方法をまとめて解説してみた
- 目次
- 履歴
2013年4月26日 初版
さくらのVPSでのnginx の設定例
以下は、Nginx + php-fpm をさくらのVPSで使ってみた で使用した さくらのVPS での nginx の設定例を FastCGIキャッシュ用に編集したものです。
今回のFastCGIキャッシュに関する編集箇所は、
赤:FastCGIキャッシュに関する追加あるいは編集箇所、青:Wordpress関連事項の追加あるいは設定箇所
で、それぞれ色分けしています。
/etc/nginx/nginx.confの設定例
|
|
/etc/nginx/php_execの設定例
|
|
nginx http部
fastcgi_buffer_size 8k;
ここでは、バッファサイズを8kにしています。
fastcgi_buffers 100 8k;
ここでは、バッファサイズを8kにし、個数を100個まで持つように設定しています。
fastcgi_cache_path /var/cache/nginx/domain1.com levels=1:2 keys_zone=cache_domain1.com:15m inactive=7d max_size=1000m;
キャッシュされたデータはファイルに格納されています。 プロキシされたURLのMD5ハッシュは、キャッシュエントリのキーとして使用され、応答の内容とメタデータのキャッシュのパスにファイル名としても使用されます。
レベルのパラメータは、キャッシュ内のサブディレクトリレベル数を設定します。
levels=1:2
ここでは、levels=1:2と指定しています。つまり、1階層目は1文字、2階層目は2文字でサブディレクトリが作成されることを意味します。
keys_zone=cache_domain1.com:15m
ここでは、ゾーン名をcache_domain1.comとし、ゾーンサイズを15MBで指定しています。ここで、メモリが15MB消費されることに注意してください。
inactive=7d
ここでは、7日間( 7d )を指定しています。つまり、特別に何もなければキャッシュは、一週間保存されることになります。
max_size=1000m;
ここでは、1000MBつまり1GBと指定しています。ここでは、zone_size と max_sizeのいずれかががサイズオーバーになった時点でキャッシュが停止します。
fastcgi_temp_path /var/cache/nginx/temp 1 2;
ここでもfastcgi_cache_pathと同じようにlevelを追加で指定することができます。しかし、一般的にレベルは使わないことが多いようです。
ここでは、fastcgi_cache_pathのレベルと同じにしています。
fastcgi_connect_timeout 60;
ここでは、60(秒)を設定しています。
fastcgi_read_timeout 90;
ここでは、90(秒)と若干長めに設定しています。
phpの処理などで応答までの最大となる時間を設定するのが良いとされています。
fastcgi_send_timeout 60;
ここでは、60(秒)を設定しています。
fastcgi_cache_valid 200 2h; fastcgi_cache_valid 302 2h; fastcgi_cache_valid 301 4h; fastcgi_cache_valid any 1m;
ここでは、以下のように設定しています。
HTTPステータスコード | キャッシュ時間 |
---|---|
200 (OK:OK) | 2時間 (2h) |
302 (Moved Temporarily:一時的に移動) | 2時間 (2h) |
301 (Moved Permanently:恒久的に移動) | 4時間 (4h) |
上記以外 | 1分 (1m) |
nginx server部
listen 80;
一般的に公開するウェブサーバーなら80番を使います。
SSLの場合は、443番を使います。
server_name domain1.com www.domain1.com;
ここでは、domain1.com と www.domain1.com の2つを同時に定義しています。
access_log /var/log/httpd/domain1.com.access.log main;
ここでは、アクセスログをログフォーマットmain の形式で、/var/log/httpd/domain1.com.access.log へ保存します。
error_log /var/log/httpd/domain1.com.error.log;
ここでは、/var/log/httpd/domain1.com.error.log へ保存します。
if ($http_host = domain1.com) { rewrite (.*) http://www.domain1.com$1; }
domain1.com、www.domain1.comいずれも使えるように設定されています。
上記の2つのホスト名でアクセスされて違うコンテンツが表示されるのであれば良いですが、同じものが表示されるのであればSEO的に良くないので、ここでは、www.domain1.comに統一しています。
try_files $uri $uri/ /index.php?q=$uri&$args;
要求されたURIが、ファイルあるいはディレクトリが存在するかチェックし、存在しない場合は、
index.php
へリダイレクトします。
# fastcgi-cache
set $do_not_cache 0;
### wordpress cache common settings.
# check to do not cache
# -- POST ?
if ($request_method = "POST") {
set $do_not_cache 1;
}
# -- Login or Comment or Post Editting ?
if ($http_cookie ~ ^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$) {
set $do_not_cache 1;
}
# -- mobile ?
if ($http_x_wap_profile ~ ^[a-z0-9\"]+) {
set $do_not_cache 1;
}
# -- Mobile ?
if ($http_profile ~ ^[a-z0-9\"]+) {
set $do_not_cache 1;
}
# -- Kei-tai ?
if ($http_user_agent ~ ^.*(2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800).*) {
set $do_not_cache 1;
}
# -- Mobile ?
if ($http_user_agent ~ ^(w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-).*) {
set $do_not_cache 1;
}
# -- Kei-tai ?
if ($http_user_agent ~ ^(DoCoMo/|J-PHONE/|J-EMULATOR/|Vodafone/|MOT(EMULATOR)?-|SoftBank/|[VS]emulator/|KDDI-|UP\.Browser/|emobile/|Huawei/|IAC/|Nokia|mixi-mobile-converter/)) {
set $do_not_cache 1;
}
# -- Kei-tai ?
if ($http_user_agent ~ (DDIPOCKET\;|WILLCOM\;|Opera\ Mini|Opera\ Mobi|PalmOS|Windows\ CE\;|PDA\;\ SL-|PlayStation\ Portable\;|SONY/COM|Nitro|Nintendo)) {
set $do_not_cache 1;
}
### wordpress cache common settings.
$do_not_cache
への設定を行っています。- post処理中の場合
- WordPressにログイン中、コメント中、記事作成中の場合
- 携帯およびモバイル機器からのアクセスの場合
fastcgi_no_cache $do_not_cache;
ブランク以降に指定するパラメータの少なくとも1つ以上の値が0でない場合は、応答情報をキャッシュしません。
fastcgi_cache_bypass $do_not_cache;
ブランク以降に指定するパラメータの少なくとも1つ以上の値が0でない場合は、キャッシュされた情報から応答を返信しません。
fastcgi_cache_key $scheme://$host$request_uri
ここで設定する情報が、キャッシュ情報を読み込むときのキー情報になります。そのため、正しく設定しないと思わぬキャッシュ情報が表示されてしまうことがあります。
ここでは、
$scheme://$host$request_uri
と指定しています。fastcgi_cache cache_domain1.com;
http部で設定したfastcgi_cache_pathのキャッシュゾーン名を指定します。
ゾーン名自体は、複数のlocationで使用することができます。
location ~* \.(gif|jpg|png|ico|css|js)$ { access_log off; } location ~ /wp-admin { access_log off; include php_exec; } location ~ /wp-content { access_log off; include php_exec; } location ~ /wp-includes { access_log off; include php_exec; } location ~ /wp-cron.php { access_log off; include php_exec; } location ~ /wp-login.php { access_log off; include php_exec; } location ~ /wp-comments { access_log off; include php_exec; } include php_exec;
- /wp-admin
- /wp-content
- /wp-includes
- /wp-cron.php
- /wp-login.php
- /wp-comments
php_exec部
PHPのファイル拡張を持つ場合の動作を定義します。
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
fastcgi_pass 127.0.0.1:9000;
ここでは、FastCGIのサーバーおよびポート番号を設定します。
fastcgi_index index.php;
ここで指定されたファイル名は、
/
で終了しているURIの場合、変数$fastcgi_script_name
に格納されます。fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
ここでは、
SCRIPT_FILENAME
パラメータを $document_root + $fastcgi_script_name
定義しています。
include fastcgi_params;
リバースプロキシは、もう一つサーバーを立ち上げる感じですが、こちらは一つのサーバーの中でキャッシュができるイメージで、リソース的にも設定の手間からも かなり楽ですね。
さらに、 ここで使用したディレクティブは、ほとんどが、Nginxでのリバースプロキシの設定例 でも同じ機能を持つディレクティブを使用していたため、 そちらをを理解されている方であれば、これは、非常に簡単だったのではないかと思います。
セッティングの楽さもさることながら、Nginxがこれだけキャッシュ機能で有名になったかというと、そもそもが、静的なページ(ファイル)の速度が非常に安定して、高速だったのが一つの要因だと思います。 加えて、この fastcgi cache で動的なページの速度が向上したことで、全体的な速度向上と安定感をもたらしたのだと思います。
逆にApacheは、静的なページ(ファイル)の速度が最初こそ速いのですが、リクエスト数が増えてくると、もっさりとした動作になってしまいます。 そのため、Squidやvarnish などキャッシュエンジンと呼ばれるキャッシュに特化したサーバーが重宝され、有名になったという経緯があります。
Squidやvarnish などが静的なページ(ファイル)も含めてキャッシュ化による高速化を図るのに対して、 Nginxは、そもそも静的なページ(ファイル)の速度は安定して速いので、動的ページだけのキャッシュ化による高速化で全体的な速さを図っています。 あらためて、Nginxは良くできてるなぁと感心しています。
また、ここで設定したディレクティブは一部です。 まだまだ設定できる情報も多いので、詳しい(設定できる)ディレクティブ情報は、nginxのホームページ( http://wiki.nginx.org/HttpFastcgiModule )を参照してください。
このFastCGIキャッシュは、リバースプロキシ以上にサーバーにやさしく、高速化、効率化が望めます。
もし、速度やリソースに不満のある方は、一度、試すのもありだと思います。
ここでは、さくらのVPS の最もリソースの少ない1Gプラン を使用して確認しました。これでも十分いけますね。
さくらのVPSのお申し込みは、http://vps.sakura.ad.jp/ からどうぞ。
このサイトでは、コンテンツの一部が非表示、あるいは、コメント、お問い合わせの投稿ができない、検索ができないことがあります。
コメントを投稿 :