WordPress高速化の効果測定

今までに行ってきたWordpressの高速化設定ですが、どの程度の効果があるかベンチマークしてみました。

試験環境
さくらのVPS 2G/FreeBSD8.2(64bit)
nginx/1.2.3 + php/5.2.17
Wordpress3.5

試験コマンド
同時接続10で10秒間テストを実行

ab -c 10 -t 10 https://mmio.net/ 

素の状態
APC:OFF, Cache:OFF

Server Software:        nginx/1.2.3
Server Hostname:        mmio.net
Server Port:            80

Document Path:          /
Document Length:        45331 bytes

Concurrency Level:      10
Time taken for tests:   12.473 seconds
Complete requests:      21
Failed requests:        0
Write errors:           0
Total transferred:      1266922 bytes
HTML transferred:       1260862 bytes
Requests per second:    1.68 [#/sec] (mean)
Time per request:       5939.750 [ms] (mean)
Time per request:       593.975 [ms] (mean, across all concurrent requests)
Transfer rate:          99.19 [Kbytes/sec] received

なにもチューニングしてない状態のWordpressだと1.68件/秒しか処理できませんでした。
Wordpressは重いと良く言われていますが、思わず納得してしまいそうな遅さです。

APCを使ってPHPを高速化
APC:ON, Cache:OFF

Server Software:        nginx/1.2.3
Server Hostname:        mmio.net
Server Port:            80

Document Path:          /
Document Length:        45329 bytes

Concurrency Level:      10
Time taken for tests:   10.021 seconds
Complete requests:      130
Failed requests:        0
Write errors:           0
Total transferred:      6012923 bytes
HTML transferred:       5985653 bytes
Requests per second:    12.97 [#/sec] (mean)
Time per request:       770.837 [ms] (mean)
Time per request:       77.084 [ms] (mean, across all concurrent requests)
Transfer rate:          585.98 [Kbytes/sec] received

APCによりPHP実行が高速化されたため、12.97件/秒と大幅に速度が向上しています。
この程度の処理能力があれば、普通に使う分には何も不満は感じないはずです。
と言うか、10万PV/dayとかのブログでも余裕で捌けそうな気がします・・・

Nginx ProxyCacheを使った高速化
APC:ON, Cache:ON

Server Software:        nginx/1.2.3
Server Hostname:        mmio.net
Server Port:            80

Document Path:          /
Document Length:        45337 bytes

Concurrency Level:      10
Time taken for tests:   10.000 seconds
Complete requests:      24795
Failed requests:        0
Write errors:           0
Total transferred:      1129185044 bytes
HTML transferred:       1124176252 bytes
Requests per second:    2479.50 [#/sec] (mean)
Time per request:       4.033 [ms] (mean)
Time per request:       0.403 [ms] (mean, across all concurrent requests)
Transfer rate:          110271.78 [Kbytes/sec] received

Nginx ProxyCacheによる動的コンテンツの再利用は効果が絶大です。
2479.5件/秒と、ちょっと意味が分からない速度となっています。

NginxのProxyCacheが必要な状況と言うのがちょっと思い浮かばないので、
Wordpressを快適に使うにはAPCでPHPを高速化するだけで十分じゃね?
と言う事で良いですかね?
だめ?

NginxでProxy Cacheしてみた

年末に少しだけ書いたWordpressの高速化ですが、高速化の最終系とも言える
Nginx proxy cacheに手を出してみました。

性能強化しても、アクセスなんて殆ど無いんですけどね。
やってみたいから設定した! ただそれだけです。

基本方針としては

  • 静的コンテンツも動的コンテンツも可能な限りキャッシュする。
  • モバイル系デバイスからの接続はキャッシュしない。
  • 管理画面はキャッシュしない。
  • ログイン中はキャッシュしない。
  • 記事のポストやコメント書き込みがあったらキャッシュを破棄する。

で、こんな感じで設定してみました。

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    directio        8m;
    keepalive_timeout  10;

    gzip              on;
    gzip_http_version 1.1;
    gzip_types        text/plain
                      text/xml
                      text/css
                      application/xml
                      application/xhtml+xml
                      application/rss+xml
                      application/atom_xml
                      application/javascript
                      application/x-javascript ;
    gzip_disable      "MSIE [1-6]\." "Mozilla/4";
    gzip_comp_level   1;
    gzip_proxied      off;
    gzip_vary         on;
    gzip_buffers      4 8k;
    gzip_min_length   1000;

    proxy_cache_path   /var/tmp/nginx/cache levels=1:2 keys_zone=czone:8m max_size=100m inactive=7d;
    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;
    proxy_cache_valid  200                1d;
    proxy_cache_valid  any                10m;
    
    upstream backend {
        ip_hash;
        server 127.0.0.1:8080;
    }

### front cache ###
    server {
        listen       80;
        server_name  mmio.net;
        
        location /wp-admin { proxy_pass http://backend; }
        location ~ .*\.php { proxy_pass http://backend; }
        location / {
            proxy_pass         http://backend;
            proxy_no_cache     $do_not_cache;
            proxy_cache_bypass $do_not_cache;
            proxy_cache czone;
            proxy_cache_key    $uri$is_args$args;

            if ($http_user_agent ~* '(DoCoMo|UP\.Browser|SoftBank|WILLCOM|emobile|iPhone|iPod|Android.*Mobile)') {
                set $do_not_cache 1;
            }
            if ($http_cookie ~* "comment_author_[^=]*=([^%]+)%7C|wordpress_logged_in_[^=]*=([^%]+)%7C") {
                set $do_not_cache 1;
            }
        }
        location ~ /purge(/.*) {
           allow 127.0.0.1;
           allow 49.212.135.193;
           deny all;
           proxy_cache_purge czone $1$is_args$args;
        }
    }    

### backend server ###
    server {
        listen       8080;
        server_name  mmio.net;
        access_log  /var/log/nginx-backend.log;

        location / {
            root   /home/www/blog/ ;
            index  index.html index.htm index.php;
            ## static files ##
            if (-f $request_filename) {
                expires 14d;
                break;
            }
            try_files $uri $uri/ /index.php;
	    }
        location ~ \.php$ {
            fastcgi_pass   unix:/tmp/php.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /home/www/blog/$fastcgi_script_name;
            include        fastcgi_params;
        }
        location = /favicon.ico { log_not_found off; }
        location = /robots.txt  { log_not_found off; }
        location ~ /\.ht { deny  all; }
    }
}

この設定で、動的コンテンツは1日、静的コンテンツは14日のキャッシュが行われます。
Wordpressのキャッシュ制御プラグインへのインタフェースも用意したので、
更新時のキャッシュ破棄も問題なしです。
これで、アクセス数が激増しても大丈夫!

ほとんどアクセス無いんだけどね(´・ω・`)

最適化(3)

今度はWordpress側の高速化についてです。

基本的にはAPCが導入された環境であれば、デフォルト状態のWordpressでも十分速いと思います。
ですが、これでは面白みがないのでWordpressを高速化させるプラグインを導入しました。

導入したのは次のプラグインです。

  • DB Cache Reloaded Fix
  • APC Object Cache Backend
  • MO Cache
  • Head Cleaner

静的コンテンツを生成して高速化させるタイプのプラグインは導入を見送りました。
相性の悪いプラグインがあったりするので、安定動作させるのが面倒です(´・ω・`)

DB Cache Reloaded Fix
データベースのクエリの出力結果など、 データベースとのやり取りをキャッシュするプラグインです。
データベースとの直接のアクセスが減りますので、記事が多くなってきたり、アクセスが集中したときに
パフォーマンスの低下を抑える効果が見込めます。

キャッシュ有効期限の初期値が5分と短いため、ある程度大きな値に増やしたほうが良いと思います。

WordPressのバージョンアップを行うときは、安全のためキャッシュ無効にしましょう。

APC Object Cache Backend
WordpressのObject Cache機能を使うためのプラグインです。

このプラグインはインストール方法が特殊なため注意が必要です。
プラグインインストール後に wp-content/plugins/apc/object-cache.php ファイルをwp-content/
直下にコピーしてからプラグインの有効化を行います。
(コピーすれば有効化しなくても動きそうな気はしますが念のため)

Object CacheをAPCで行うため、APCが導入されている必要があります。
APCが使えない場合はWP File CacheプラグインでObject Cacheが使えるようになります。
こちらはプラグインの有効化を行うと自動的にwp-content/object-cache.php を用意してくれます。

MO Cache
MO Cache では他言語対応で使う .moファイルのオブジェクトをキャッシュし、
次回アクセス以降はキャッシュを使って高速化を行うプラグインです。
日本語版のWordpressや日本語対応のプラグインを使用している場合は高速化が期待できます。
Object Cacheが必要なためAPC Object Cache BackendまたはWP File Cacheをインストールしておく
必要があります。

このプラグインはインストール方法が特殊なため注意が必要です。
最大限の効果を発揮させるためにMust Use Pluginsとしてインストールを行う必要があります。

  1. Verify that /wp-content/object-cache.php is installed.
  2. Create /wp-content/mu-plugins directory, if it not exist.
  3. Upload mo-cache.php to the /wp-content/mu-plugins directory.
  4. Done! No need to activate.

との事ですので、まずは普通にインストールしてから次の作業を行います。

  1. /wp-content/ に object-cache.php があることを確認する
  2. /wp-content/mu-plugins ディレクトリが無ければ作成する
  3. /wp-content/mu-plugins に mo-cache.php をアップロード(wp-content/plugins/mo-cache/mo-cache.phpをコピーする)
  4. インストール完了です。 プラグインの有効化は必要ありません。

Head Cleaner
ヘッダーとフッターを解析して、余計なタグの削除やCSS,Javascriptの送信順序の最適化などを行ってくれます。

この辺りを参考に設定してください。

以上、簡単ですがWordpressの高速化について書いてみました。

最適化(2)

前の記事をPOSTしたら、結果じゃなくて手順を書けと言われてしまいました(´・ω・`)

と言うわけで簡単にWordpressの高速化について書きます。

まずは、Server側について。
Webサーバー
最近はサーバーも回線も強力ですので、深く考えずに設定しても十分な性能が発揮できます。
ですが、送信するデータ量を減らしたほうが望ましいことは確かです。
と言うわけで送信データ量を減らすため、Expiresヘッダの追加とGzip圧縮を導入しました。

Expiresヘッダの追加により、ブラウザ側でコンテンツのキャッシュが働き送信データの減少が行えます。
画像ファイル(jpg,png,gif,ico)とCSS、JavascriptにExpiresヘッダを付加することにしました。

さらにGzip圧縮を行うことにより送信データ量を減らします。
圧縮率の高いテキストデータにのみGzip圧縮を行うこととします。

うちのサーバーはNginxを使っているので、こんな感じでgzipとExpiresの設定を行っています。
Apacheは設定は適当にググってください。

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile           on;
    directio           8m;
    keepalive_timeout  10;

    gzip               on;
    gzip_http_version  1.1;
    gzip_types         text/plain
                       text/xml
                       text/css
                       application/xml
                       application/xhtml+xml
                       application/rss+xml
                       application/atom_xml
                       application/javascript
                       application/x-javascript ;
    gzip_disable       "MSIE [1-6]\." "Mozilla/4";
    gzip_comp_level    1;
    gzip_proxied       off;
    gzip_vary          on;
    gzip_buffers       4 8k;
    gzip_min_length    1000;

    server {
        listen         80;
        server_name    mmio.net;

        location / {
            root   /home/www/blog/ ;
            index  index.php;
            location ~* \.(jpg|jpeg|gif|css|png|js|ico)$ {
                expires 14d;
            } 
        }
        location ~ \.php$ {
            fastcgi_pass   unix:/tmp/php.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /home/www/blog/$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
}

PHP
元から高速化設定の導入済みのため、今回の作業とは直接の関係はありませんが……
PHP実行時に毎回毎回スクリプトのコンパイルが行われるのは効率が悪いため、
このサーバーではPHPアクセラレータAPC(Alternative PHP Cache)を導入しています。
APCを簡単に説明すると、
PHP実行時にコンパイル済みのバイナリをキャッシュし、再実行時はコンパイル無しで高速実行するというものです。

有名なモジュールですので導入方法とかは割愛します。
うちのサーバーではこんな感じの設定になっています。

apc.enabled = 1
apc.shm_size = 96M
apc.ttl = 3600
apc.user_ttl = 3600
apc.gc_ttl = 7200
apc.mmap_file_mask = /dev/zero
apc.max_file_size = 8M

WordPress本体については後ほど書きます。

最適化

アクセス数がたいして多くもない当ブログですが、高速化すべく設定などの最適化を行ってみました。

1

GTmetrixの解析で
Page Speed Grade: A
YSlow Grade: B

との判定がもらえましたので、十分な最適化が出来てるはずです。

最適化の内容を書こうかと思いましたが・・・
面倒くせぇ(‘A`)

Macのメモリ解放スクリプト

以前に書いたメモリ解放スクリプトを少し改良しました。

#!/bin/sh

INACTIVE_THRESHOLD=8192
FREE_THRESHOLD=1024

VM_STAT=$(vm_stat)
    FREE=$(echo "$VM_STAT" | awk '/Pages free/ {print $3}' | tr -d '.')
    ACTIVE=$(echo "$VM_STAT" | awk '/Pages active/ {print $3}' | tr -d '.')
    INACTIVE=$(echo "$VM_STAT" | awk '/Pages inactive/ {print $3}' | tr -d '.')
    SPECULATIVE=$(echo "$VM_STAT" | awk '/Pages speculative/ {print $3}' | tr -d '.')
    WIRED=$(echo "$VM_STAT" | awk '/Pages wired down/ {print $4}' | tr -d '.')

INACTIVE=$(expr $INACTIVE / 256)
FREE=$(expr \( $SPECULATIVE + $FREE \) / 256)

if [ $INACTIVE -gt $INACTIVE_THRESHOLD ] || [ $FREE -le $FREE_THRESHOLD ];  then
  #purge
  du -sx / >& /dev/null & sleep 15 && kill $! >/dev/null 2>&1
fi

以前はINACTIVEだけ監視してましたが、空きメモリも監視するようにしました。

これでMacbook Airでも戦えるはず……

サンプルだとINACTIVEが8192MB以上または空きメモリが1024MB以下になるとメモリ解放を試みます。

トライエックス!これを4号か5号で焼いてこそ味がでる

タイトルは、ゆうきまさみ「究極超人あ〜る」の鳥坂先輩が言った迷セリフです。
極端な意見では有りますが、極端なほうが味が出ると言うのも確かです。

このセリフに出てきてる用語を簡単に説明すると
トライエックス(Tri-X)
コダック製のISO400でコントラスト高めの白黒フィルム。
驚くべきことに誕生は1954年! 60年近くも使われ続けているフィルムだったりします。

4号か5号
白黒写真用の印画紙の規格、号数が大きいほどコントラストが高くなります。
5段階?なので4号 5号はコントラストがかなり高めになります。

つまり、コントラスト高めのフィルムで撮影してコントラスト高めの印画紙に焼け! と言うことです。
これに従うと、階調?なにそれ? って感じでハイコントラストな仕上がりになります。

上手くハマれば格好良い写真に仕上がるため、つい多用してしまいます。
と言うわけで、簡単に鳥坂仕様の加工をするためにLightroom4でプリセットを作っちゃいました。
鳥坂プリセット

前の記事の写真で使った設定をプリセット化したものです、Lightroom4に読み込ませればそのまま使えるはず?

鳥坂先輩

鳥坂先輩の迷言「トライエックス!これを4号か5号で焼いてこそ味がでる」にしたがって、
トライエックス風プリセットと5号ペーパー風プリセットを組み合わせてみました。

鳥坂先輩の言う味ってこんな感じなんですかね?