マネージドWebホスティングからVPSへブログを移行する際に最低限の努力で最大限の高速化を行う

このブログやもう一つのブログは、これまで所謂マネージドWebホスティング(利用者はコンテンツを上げるだけでWebサーバ運用はホスティング会社が受け持つ)を利用していました。

しかしよく考えると、自分自身レンサバ屋をやってきて、さらには自分でWebサービスの高度化に関する研究をやっているのに、自分でWebサーバを管理していないのはこれいかに、と思い始めて急遽VPSを借りました。

これで、Apacheをコンパイルしてmod_mrubyやその他もろもろの自作モジュールを組み込んで、最強のWebホスティング環境を構築するぜ!と思っているわけですが、せっかくVPS上でroot権限で自由にサーバカスタマイズができるわけですから、とりあえずブログのパフォーマンスを楽に手間なく高速化してやろうと思ったわけです。

ということで、今回は細やかなチューニングをするのではなく、如何に手を抜いて最大限の高速化を得られるか、を目標にします。また、僕自身が二つブログを持っているので、その二つをバーチャルホストを使って同時に高速化する設定をしたいと思います。

まずはWordpressの移行

これが面倒なのですが、今回は一からWordpressをインストールすのではなく、以下の手順で移行しました。

1. DBをmysqldumpで抜き出す

こんなシェルスクリプトで抜き出して、ファイルを移行先に持っていきました。

[program lang=’bash’ escaped=’true’]

file="./mysql_backup.txt"
config="./blog.matsumoto-r.jp/wp-config.php"

host=`grep DB_HOST $config ¦ awk -F¥' '{print $4}'`
db=`grep DB_NAME $config ¦ awk -F¥' '{print $4}'`
user=`grep DB_USER $config ¦ awk -F¥' '{print $4}'`
pass=`grep DB_PASSWORD  $config ¦ awk -F¥' '{print $4}'`

mysqldump -h $host -p$pass -u$user $db > $file
tar zcvf $file.tar.gz $file

[/program]

2.  ファイルをまとめてもっていく

blog.matsumoto-r.jp以下にwordpressのファイルがあるので、ディレクトリごと移行先にもっていきました。

3. mysqlに1のSQLを流し込む

事前にdbとmysqlのユーザやパスワードは作っておいて下さい。

4. ドキュメントルートにwordpressのディレクトリをまるごとコピー

ownerの変更などもして下さい。

5. wp-config.phpのDB情報書き換え

3.で設定したDBの情報に書き換えます。

5. DNSのレコード書き換え

わーい、これで移行完了です。一応失敗したときにすぐDNSのレコードを戻せるように、前のブログはそのままそっとしておきましょう。

手っ取り早い高速化

ここからは、手っ取り早く最大限のパフォーマンスを得たいと思います。目標は5分で高速化してしまいましょう。色々チューニングの方法があると思うのですが、自分のブログなんだからそこまで緻密にならず最も簡単に高速化する方法を選択しましょう。ぱっと思いつくのは、Nginxによるキャッシュコントロールです。

ということで、その手順をざっくり紹介します。

NginxとApacheとWordpressを入れる

WordPressで必要なPHPのライブラリなどを手っ取り早く入れるために、CentOS6ならばyumで一気にwordpressまで入れてしまいましょう。入れるだけで、このwordpress自体は使わないので、conf.d/wordpress.confはリネームしておけばよいでしょう。

[program lang=’bash’ escaped=’true’]

yum intall nginx httpd wordpress

[/program]

一応apcは入れておく

PHPを使うのですから、とりあえずapcぐらいは入れておきましょう。CPUの負荷が場合によっては低減できます。

[program lang=’bash’ escaped=’true’]

yum -y install php-devel php-pear gcc httpd-devel pcre-devel
pecl install apc
echo "extension=apc.so" >/etc/php.d/apc.ini

[/program]

これでOKです。

Apacheのバーチャルホストの設定

今回は二つのブログがあるので、それをnginxでまとめてプロキシする際の設定を紹介します。confを見れば大体分かると思います。

[program lang=’apache’ escaped=’true’]

Listen 127.0.0.1:8080
Listen 127.0.0.1:8081

NameVirtualHost 127.0.0.1:8080
NameVirtualHost 127.0.0.1:8081

<VirtualHost 127.0.0.1:8080>
  DocumentRoot /var/www/html/blog
  ServerName blog.matsumoto-r.jp
</VirtualHost>

<VirtualHost 127.0.0.1:8081>
  DocumentRoot /var/www/html/moblog
  ServerName moblog.matsumoto-r.jp
</VirtualHost>

[/program]

このように、IPベースのVirtualHostで複数のポートでLISTENするようにしておきます。

Nginxの設定

次は上記で設定したApacheに対してキャッシュコントロールとリバースプロキシを提供するための設定を行います。ちなみ、今回はnginxで扱うファイル群もapacheユーザで操作可能なように、nginxのユーザをapacheユーザにしておきましょう。設定は以下になります。サーバのCPUコアは2つでした。色々なサイトを参考にした結果、以下のような設定に落ち着きました。

nginx.conf

[program lang=’c’ escaped=’true’]

user                apache;
worker_processes    2;
error_log           /var/log/nginx/error.log;
pid                 /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    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  main;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

[/program]

conf.d/default.conf

[program lang=’actionscript3′ escaped=’true’ line=’1′]

proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=czone:4m max_size=50m inactive=120m;
proxy_temp_path   /var/tmp/nginx;
proxy_cache_key   "$scheme://$host$request_uri";
proxy_set_header  Host               $host;
proxy_set_header  X-Real-IP          $remote_addr;
proxy_set_header  X-Forwarded-Host   $host;
proxy_set_header  X-Forwarded-Server $host;
proxy_set_header  X-Forwarded-For    $proxy_add_x_forwarded_for;

upstream blog_backend {
    ip_hash;
    server 127.0.0.1:8080;
}

upstream moblog_backend {
    ip_hash;
    server 127.0.0.1:8081;
}

server {
    listen       80;
    server_name  blog.matsumoto-r.jp;
    root         /var/www/html/blog;

    location /wp-admin {
        proxy_pass http://blog_backend;
    }

    location ~ .*¥.php {
        proxy_pass http://blog_backend;
    }

    location ~ /¥.ht {
        deny  all;
    }

    location ~ .*¥.(txt¦xml¦html?¦js¦css¦gz¦ico¦jpe?g¦gif¦png¦wmv¦flv¦swf¦mpg) {
        access_log  off;
        expires 30d;
        break;
    }

    location / {
        set $mobile "";
        if ($http_user_agent ~* '(DoCoMo¦J-PHONE¦Vodafone¦MOT-¦UP¥.Browser¦DDIPOCKET¦ASTEL¦PDXGW¦Palmscape¦Xiino¦sharp pda browser¦Windows CE¦L-mode¦WILLCOM¦SoftBank¦Semulator¦Vemulator¦J-EMULATOR¦emobile¦mixi-mobile-converter)') {
            set $mobile "@ktai";
        }
        if ($http_user_agent ~* '(iPhone¦iPod¦Opera Mini¦Android.*Mobile¦NetFront¦PSP¦BlackBerry)') {
            set $mobile "@mobile";
        }
        if ($http_cookie ~* "comment_author_¦wordpress_(?!test_cookie)¦wp-postpass_" ) {
            set $do_not_cache 1;
        }
        proxy_no_cache     $do_not_cache;
        proxy_cache_bypass $do_not_cache;
        proxy_cache czone;
        proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
        proxy_cache_valid  200 301 302 10m;
        proxy_cache_valid  404 5m;
        proxy_pass http://blog_backend;
    }

}

server {
    listen       80;
    server_name  moblog.matsumoto-r.jp;
    root         /var/www/html/moblog;

    location /wp-admin {
        proxy_pass http://moblog_backend;
    }

    location ~ .*¥.php {
        proxy_pass http://moblog_backend;
    }

    location ~ /¥.ht {
        deny  all;
    }

    location ~ .*¥.(txt¦xml¦html?¦js¦css¦gz¦ico¦jpe?g¦gif¦png¦wmv¦flv¦swf¦mpg) {
        access_log  off;
        expires 30d;
        break;
    }

    location / {
        set $mobile "";
        if ($http_user_agent ~* '(DoCoMo¦J-PHONE¦Vodafone¦MOT-¦UP¥.Browser¦DDIPOCKET¦ASTEL¦PDXGW¦Palmscape¦Xiino¦sharp pda browser¦Windows CE¦L-mode¦WILLCOM¦SoftBank¦Semulator¦Vemulator¦J-EMULATOR¦emobile¦mixi-mobile-converter)') {
            set $mobile "@ktai";
        }
        if ($http_user_agent ~* '(iPhone¦iPod¦Opera Mini¦Android.*Mobile¦NetFront¦PSP¦BlackBerry)') {
            set $mobile "@mobile";
        }
        if ($http_cookie ~* "comment_author_¦wordpress_(?!test_cookie)¦wp-postpass_" ) {
            set $do_not_cache 1;
        }
        proxy_no_cache     $do_not_cache;
        proxy_cache_bypass $do_not_cache;
        proxy_cache czone;
        proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
        proxy_cache_valid  200 301 302 10m;
        proxy_cache_valid  404 5m;
        proxy_pass http://moblog_backend;
    }

}

[/program]

これで、高速化は完了です。NginxとApacheを起動させて、無事Wordpressが動作していることを確認しましょう。

パフォーマンス結果

では、最後にパフォーマンス比較をしておきます。同時接続数10総接続数1000ぐらいでabベンチをかけました。

上記作業をせず、同じVPS上で普通にApacheでWordpressを動かした場合

[program lang=’c’ escaped=’true’]

Server Software:        Apache
Server Hostname:        moblog.matsumoto-r.jp
Server Port:            80

Document Path:          /
Document Length:        34968 bytes

Concurrency Level:      10
Time taken for tests:   213.396 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      35177000 bytes
HTML transferred:       34968000 bytes
Requests per second:    4.69 [#/sec] (mean)
Time per request:       2133.964 [ms] (mean)
Time per request:       213.396 [ms] (mean, across all concurrent requests)
Transfer rate:          160.98 [Kbytes/sec] received

[/program]

上記の作業を行った上で再度同一のベンチマークを行った場合

[program lang=’actionscript3′ escaped=’true’ line=’1′]

Server Software:        nginx/1.0.15
Server Hostname:        moblog.matsumoto-r.jp
Server Port:            80

Document Path:          /
Document Length:        34968 bytes

Concurrency Level:      10
Time taken for tests:   0.094 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      35183000 bytes
HTML transferred:       34968000 bytes
Requests per second:    10628.80 [#/sec] (mean)
Time per request:       0.941 [ms] (mean)
Time per request:       0.094 [ms] (mean, across all concurrent requests)
Transfer rate:          365188.54 [Kbytes/sec] received

[/program]

request/secが「4.69」から「10628.80」と、思ってた以上に早くなってしまいました。

最後に

というように、いくつかパフォーマンス向上の手法はあるのですが、今回のように自分の適当なブログを最低限の努力で最大限の高速化を得るには、この作業をやってしまうのが最も効率良いように思います。

いくつか高速化の手法を試してみたのですが、結局このNginxのキャッシュコントロール+リバースプロキシの向上が大きすぎるため、これをやってしまうのが一番楽でした。

晴れてVPSをレンタルしてみた人は、マネージドWebホスティングからVPSへブログを移行する際に、最低限の努力で最大限の高速化を是非ともこの方法で行ってみてください。