“WP Super Cache”と”nginx”で爆速WordPressサイトを構築する

nginx,さくらのVPS

さくらVPS512で、Yahoo!砲食らっても WordPress を平常運転させるための設定 | dogmap.jp」を参考に、当ブログをホストしている「さくらのVPS 2G」のサーバ設定を調整したら、1万アクセスを1.4秒で処理できるようになりました。

結論から言うと「nginxすごいわー。」なんですが、その構成やら設定やらをさらしてみようと思います。

大まかな仕組み

1回目のアクセスは通常通りWordPressが動作します。

この時、キャッシュプラグイン「WP Super Cache」がキャッシュファイルを生成します。

2回目以降のアクセスはnginxがキャッシュファイルを探し、見つかればキャッシュファイルを送信します。

こうする事により、キャッシュが効いたページではWordPressが介在しない静的なページ送信処理に置き換わります。

この構成は「分かりやすい」のがメリットで、他にも任意のタイミングで簡単にキャッシュクリアが出来る事、それとキャッシュ期間を長めに取れるのが気に入ってます。

サーバ構成

「さくらのVPS 2G」にUbuntuを入れ、Webサーバとしてnginxを動かし、PHPはFastCGIを利用しています。

詳細は以前に書いた「「さくらのVPS 2G」+ Ubuntuで”WordPress on nginx with FastCGI”環境を構築する」を参照してください。

nginxの設定

現在利用しているnginx.confの内容を下記に示します。

$ cat /etc/nginx/nginx.conf
user www-data;
worker_processes 3;
worker_cpu_affinity 001 010 100;
pid /var/run/nginx.pid;

events {
        worker_connections 1024;
        multi_accept off;
        use epoll;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        keepalive_timeout 5;
        server_tokens off;
        server_name_in_redirect off;
        port_in_redirect  off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Logging Settings
        ##

        log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip_static         on;
        gzip                on;
        gzip_comp_level     6;
        gzip_types          text/plain text/xml text/css text/javascript
                            application/xhtml+xml application/xml
                            application/rss+xml application/atom_xml
                            application/javascript application/x-javascript;
        gzip_disable        "MSIE [1-6]\.";

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;

        client_max_body_size 32m;
        client_body_buffer_size 256k;
}

ホスト設定

現状のサイト設定ファイルは以下の通りです。

冒頭にも書きましたが、WordPress用キャッシュプラグイン「WP Super Cache」用に最適化してあります。

server {
        listen   80;

        root /home/USER_NAME/www;
        index index.php index.html index.htm;
        charset utf-8;

        server_name www.hide10.com;

        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt { access_log off; log_not_found off; }
        location = /apple-touch-icon.png { access_log off; log_not_found off; }
        location = /apple-touch-icon-precomposed.png { access_log off; log_not_found off; }

        # Deny all attempts to access hidden files such as .htaccess, .htpasswd
        location ~ /\. {deny all;access_log off;log_not_found off;}

        location / {
                try_files $uri $uri/ /index.php?$args;
        }

        # WP Super Cache rules.
        gzip_static on;

        set $supercacheuri "";
        set $supercachefile "$document_root/wp-content/cache/supercache/${http_host}${uri}index.html";
        if (-e $supercachefile) {
                set $supercacheuri "/wp-content/cache/supercache/${http_host}${uri}index.html";
        }

        # If this is a POST request, pass the request onto WordPress.
        if ($request_method = POST) {
                set $supercacheuri "";
        }

        # If there is a query string, serve the uncached version.
        if ($query_string) {
                set $supercacheuri "";
        }

        # Logged in users and those who have posted a comment get the non-cached version.
        if ($http_cookie ~* comment_author_|wordpress_logged_in|wp-postpass_) {
                set $supercacheuri "";
        }

        # Stop processing if the supercache file is valid.
        if ($supercacheuri) {
                rewrite ^ $supercacheuri break;
        }

        location ~* \.(txt|html?|js|css)$ {
            expires 30d;
        }

        location ~* \.(png|jpe?g|gif|ico)$ {
            expires 365d;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param PHP_VALUE "upload_max_filesize = 50M";
                fastcgi_param PHP_VALUE "post_max_size = 51M";
                include fastcgi_params;
        }
}

MySQL設定

MySQL設定はこんな感じ。設定ファイル全体だと長いので、[mysqld]セクションの主要情報のみ載せています。

[mysqld]
user            = mysql
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
innodb_buffer_pool_size = 64M
innodb_log_file_size    = 16M
innodb_flush_method     = O_DIRECT
key_buffer              = 256M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
thread_cache            = 256
sort_buffer             = 256K
read_buffer_size        = 256K
read_rnd_buffer_size    = 256K
join_buffer_size        = 256K
myisam-recover          = BACKUP
max_connections         = 256
table_cache             = 256
query_cache_limit       = 2M
query_cache_size        = 128M
query_cache_type        = 1
tmp_table_size          = 256M
max_heap_table_size     = 256M
table_open_cache        = 1024

MySQLの調整では「MySQLTuner」が活躍しました。

ダウンロードしてきて “perl mysqltuner.pl"するだけなので、みんなも試してみると良いよ。

Apache Benchで性能テスト

上記の設定変更後に、性能確認のためApacheBenchを走らせてみました。

回線速度の影響を除外するため、SSHログインしたサーバ上で実行しています。

$ ab -n 10000 -c 100 https://www.hide10.com/
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 www.hide10.com (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        nginx
Server Hostname:        www.hide10.com
Server Port:            80

Document Path:          /
Document Length:        54980 bytes

Concurrency Level:      100
Time taken for tests:   1.373 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      553053538 bytes
HTML transferred:       550121194 bytes
Requests per second:    7283.37 [#/sec] (mean)
Time per request:       13.730 [ms] (mean)
Time per request:       0.137 [ms] (mean, across all concurrent requests)
Transfer rate:          393368.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   1.0      2       7
Processing:     1   12  14.2     11     224
Waiting:        0    4   3.2      3      17
Total:          4   14  14.1     13     225

Percentage of the requests served within a certain time (ms)
  50%     13
  66%     14
  75%     14
  80%     14
  90%     15
  95%     17
  98%     20
  99%     21
 100%    225 (longest request)

同時接続数100で1万リクエストを行った場合、1.4秒程度で完了するようです。

1秒あたりの処理数(Requests per second)も7000を超えており、一般的なWordPressサイトとは異次元の性能を叩き出してます。

まとめ

nginxすごいわー。

そんな感じで!