こんにちは。CSチームの坂本です。
今回はNginxのproxy cacheを利用してWordPressを高速化したいと思います。
いままでの記事
Nginx + WordPress
Nginx + WordPress 「Gzip Precompression」モジュール篇
※EC2の環境、Nginx以外のMySQL、PHP、PHP-FPMの設定などは前回、前々回と同様です。
目次
- 前回までの構成
- 今回の構成
- 設定ファイル(nginx.conf)
- 設定ファイル(default.conf)
- 比較
1. 前回までの構成
前回までの構成は以下の図のようなイメージです。
2. 今回の構成
今回は、Nginxをリバースプロキシとしてフロントエンドに追加します。
Nginxをリバースプロキシとして追加し、proxy cacheの設定をおこなうことで、以下の図のような仕組みに変わります。
キャッシュがないページにアクセスされたときは、バックエンドにアクセスし、その処理結果をキャッシュします。キャッシュがあるページへのアクセス時はフロントエンドのNginxから直接キャッシュを返します。
このような構成にすることで、PHPやDBへのアクセスが減り、レスポンスが速くなります。
▲キャッシュが存在しない場合は、バックエンドにアクセスし、キャッシュを作成します。
▲キャッシュが存在する場合は、フロントエンドのNginxが直接キャッシュを返します。
3. 設定ファイル(nginx.conf)
まず、nginx.confのhttpブロックの中にproxy_cache_pathを追加します。proxy_cache_pathはhttpブロックにしか設定できないため、こちらで設定します。
/etc/nginx/nginx.conf
http { # 省略 proxy_cache_path /var/cache/nginx/cache levels=1 keys_zone=zone1:4m inactive=7d max_size=50m; include /etc/nginx/conf.d/*.conf; }
proxy_cache_pathでキャッシュを保存するディレクトリなどを設定します。
levels=1
levelsはキャッシュを保存するサブディレクトリの階層の深さを設定します。
今回のようにlevels1と設定した場合は、/var/cache/nginx/cache/4/d95121ef50f478938544994ae1379xxx、levels1:2と設定した場合は、/var/cache/nginx/cache/4/97/d95121ef50f478938544994ae1379xxx、のような形でキャッシュが保存されます。
keys_zone=zone1:4m
キャッシュゾーンを指定します。次のdefault.confで「proxy_cache zone1」と指定して対応させます。4mはこのゾーンのキーとデータの情報の格納にメモリを4Mを使うという意味です。
inactive=7d
7日間アクセスがないキャッシュを削除するという意味です。
max_size=50m
ゾーン内に保存できるキャッシュの最大値を50Mにするという意味です。
※事前に/var/cache/nginx/cacheディレクトリを作成してください。
4. 設定ファイル(default.conf)
次に、default.confを変更します。80番ポートをリバースプロキシサーバーとして使用するように変更し、8080番ポートを追加してこちらをバックエンドのWebサーバーとして使用します。
管理画面はWebサーバーにアクセスするようにし、携帯からのアクセスをキャッシュしない設定としました。
「proxy_cache_valid 200 1d」という設定は正常に同じページにアクセスがあった場合は1日はバックエンドにアクセスせず、保存されたキャッシュを返すという意味です。
/etc/nginx/conf.d/default.conf
upstream backend { server 127.0.0.1:8080; } server { listen 80; server_name _; access_log /var/log/nginx/access_80.log main; location = /favicon.ico { log_not_found off; } location /wordpress/wp-admin { proxy_pass http://backend; } location /wordpress/wp-login.php { proxy_pass http://backend; } location = /wordpress { rewrite ^(.+)$ /wordpress/index.php; } location = /wordpress/wp-admin { rewrite ^(.+)$ /wordpress/wp-admin/index.php; } location / { proxy_pass http://backend; proxy_no_cache $do_not_cache; proxy_cache_bypass $do_not_cache; proxy_cache zone1; proxy_cache_key $scheme$proxy_host$uri$is_args$args; proxy_cache_valid 200 1d; if ($http_user_agent ~* '(DoCoMo|UP.Browser|SoftBank|WILLCOM|emobile|iPhone|iPod|Android.*Mobile)') { set $do_not_cache 1; } } } server { listen 8080; server_name _; access_log /var/log/nginx/access_8080.log main; location / { root /usr/share/nginx/html; index index.php index.html index.htm; } location ~ .php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/$fastcgi_script_name; includefastcgi_params; fastcgi_pass_header "X-Accel-Redirect"; fastcgi_pass_header "X-Accel-Expires"; } }
5. 比較
前回までの構成のようなNginxをリバースプロキシとしてフロントエンドに置いていないサーバーと、今回のリバースプロキシでproxy cacheを利用している場合の速度を比較してみたいと思います。
ローカルの環境からabコマンドでベンチーマークの測定をした結果です。
※サーバーは両方ともEC2でZoneはap-southeast-1b、Typeはt1.microとなっています。
proxy cacheなし
すべてのリクエストが完了するのにかかった時間は約5.6秒でした。
Time taken for tests: 5.604812 seconds
ab -n 50 -c 5 http://ec2-XXX-XXX-XXX-60.ap-southeast-1.compute.amazonaws.com/wordpress/?p=1 Benchmarking ec2-XXX-XXX-XXX-60.ap-southeast-1.compute.amazonaws.com (be patient).....done Server Software:nginx/1.0.15 Server Hostname:ec2-XXX-XXX-XXX-60.ap-southeast-1.compute.amazonaws.com Server Port:80 Document Path: /wordpress/?p=1 Document Length:6640 bytes Concurrency Level: 5 Time taken for tests: 5.604812 seconds Complete requests: 50 Failed requests:0 Write errors: 0 Total transferred: 344900 bytes HTML transferred: 332000 bytes Requests per second:8.92 [#/sec] (mean) Time per request: 560.481 [ms] (mean) Time per request: 112.096 [ms] (mean, across all concurrent requests) Transfer rate: 59.95 [Kbytes/sec] received
proxy cacheあり
すべてのリクエストが完了するのにかかった時間は約1.2秒でした。
Time taken for tests: 1.284296 seconds
ab -n 50 -c 5 http://ec2-XXX-XXX-XXX-124.ap-southeast-1.compute.amazonaws.com/wordpress/?p=1 Benchmarking ec2-XXX-XXX-XXX-124.ap-southeast-1.compute.amazonaws.com (be patient).....done Server Software:nginx/1.0.15 Server Hostname:ec2-XXX-XXX-XXX-124.ap-southeast-1.compute.amazonaws.com Server Port:80 Document Path: /wordpress/?p=1 Document Length:6703 bytes Concurrency Level: 5 Time taken for tests: 1.284296 seconds Complete requests: 50 Failed requests:0 Write errors: 0 Total transferred: 348200 bytes HTML transferred: 335150 bytes Requests per second:38.93 [#/sec] (mean) Time per request: 128.430 [ms] (mean) Time per request: 25.686 [ms] (mean, across all concurrent requests) Transfer rate: 264.74 [Kbytes/sec] received
約5分の1の速度になりました。何回か計測し多少ばらつきはありましたが、proxy cacheを利用していないサーバーでは5秒以上かかるのに対し、proxy cacheを利用しているサーバーでは1~2秒で完了しました。
以上のようにproxy cacheを利用すると手っ取り早くWordPressを高速化することが可能です。
次回もNginx + WordPressで高速化する方法を検討してみたいと思います。