2016年6月21日火曜日

WordPressの応答をVarnishで高速化

https://varnish-cache.org/
Varnishを使ってWordPressをキャッシュする方法です。
Varnish port 80 -> nginx port 8080 -> php-fpm -> WordPress という構成にします。

Varnishは、いままで使ったことがなかったので、導入だけでも触っておこうと考えて、よくありそうなユースケースとして、ウェブメディアの前段にキャッシュを置く、という使い方をしてみました。
ほかに、外部サービスのAPIが不安定だったりする場合、間にVarnishを挟んで、可用性とパフォーマンスを確保する使い方もあるようです。
External API Caching with Varnish & Nginx http://blog.runnable.com/post/144975295096/external-api-caching-with-varnish-nginx


以下、既に、WordPressが立っているという状況で進めていきます。
環境は、CentOS 6.7です。

Varnishをインストール
$ rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-4.1/el6/noarch/varnish-release/varnish-release-4.1-2.el6.noarch.rpm
$ yum install varnish
# varnishd -V
varnishd (varnish-4.1.2 revision 0d7404e)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2015 Varnish Software AS[

nginxの設定ファイルを編集
nginxの設定。ポート8080番で待ち受けるようにします。
# vim /etc/nginx/conf.d/default.conf
listen       80;
->
listen       8080;
https://gist.github.com/takeshiyako2/5cd855e9d3bc2e55b8cb5d5f70d1ff6e#file-default-conf

Varnishの設定ファイルを編集
Varnishのポートの設定。80番で待ち受けるようにします。
# vim /etc/sysconfig/varnish
VARNISH_LISTEN_PORT=6081
->
VARNISH_LISTEN_PORT=80
https://gist.github.com/takeshiyako2/5cd855e9d3bc2e55b8cb5d5f70d1ff6e#file-varnish

VCL(Varnish Configuration Language)の設定。
以下、設定のポイントです。
・バックエンドをnginx(127.0.0.1:8080)に
・localhostからのパージリクエストを許可(ここでは、全てのキャッシュをパージするBANを設定)
・WordPress管理者ページをキャッシュしないように
・コンテンツでは、クッキーを無視して、キャッシュが効くように
# vim /etc/varnish/default.vcl

以上で設定は完了です。

nginxとVarnishをリロード(or リスタート)
# service nginx restart
# service varnish restart
ちゃんとキャッシュされているでしょうか?
Varnishにキャッシュされたコンテンツがnginxログに出なくなっているとおもいます。
キャッシュが破棄される時間、TTLは、/etc/sysconfig/varnishで設定されています。必要に応じて編集すると良いでしょう。デフォルトでは120秒です。

キャッシュをパージするには?
curlでVarnishのAPIを叩きます。
以下のコマンドで、全てのキャッシュをパージします。
# curl -X BAN -v http://localhost/
細かくパスを指定してパージもできます。詳しくは公式ドキュメントを参照してください。
Purging and banning — Varnish version 4.1.2 documentation https://www.varnish-cache.org/docs/4.1/users-guide/purging.html

ベンチマーク
Varnishなし。
# ab -c 100 -n 10000 http://192.168.33.10/
Server Software:        nginx/1.10.1
Server Hostname:        192.168.33.10
Server Port:            80

Document Path:          /
Document Length:        10400 bytes

Concurrency Level:      100
Time taken for tests:   222.524 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      106320000 bytes
HTML transferred:       104000000 bytes
Requests per second:    44.94 [#/sec] (mean)
Time per request:       2225.244 [ms] (mean)
Time per request:       22.252 [ms] (mean, across all concurrent requests)
Transfer rate:          466.59 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   4.7      0      51
Processing:    83 2218 452.3   2118    5395
Waiting:       31 2070 435.9   1977    5210
Total:         83 2218 451.4   2119    5395

Percentage of the requests served within a certain time (ms)
  50%   2119
  66%   2250
  75%   2347
  80%   2420
  90%   2731
  95%   3164
  98%   3642
  99%   3945
 100%   5395 (longest request)
Varnishあり。
Server Software:        nginx/1.10.1
Server Hostname:        192.168.33.10
Server Port:            80

Document Path:          /
Document Length:        10465 bytes

Concurrency Level:      100
Time taken for tests:   1.546 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      107936450 bytes
HTML transferred:       104650000 bytes
Requests per second:    6466.26 [#/sec] (mean)
Time per request:       15.465 [ms] (mean)
Time per request:       0.155 [ms] (mean, across all concurrent requests)
Transfer rate:          68158.75 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    7   2.6      6      19
Processing:     3    8   2.7      8      27
Waiting:        0    5   2.9      5      18
Total:          9   15   3.4     15      29

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     16
  75%     17
  80%     17
  90%     20
  95%     22
  98%     26
  99%     27
 100%     29 (longest request)
Varnishなし 44.94 req/s、Varnishあり 6466.26 req/s。
Varnishありの転送サイズが若干多いのは、ヘッダーが付与されているからかなと。

まとめ
Varnishを導入して、WordPressの応答を高速化しました。
初歩的な使いかたはできたかな?と思います。
今回はやりませんでしたが、ディレクトリ単位、ファイル単位といった細かい粒でキャッシュのパージができます。このため、応用次第で、様々なサイトにキャッシュを導入できたりしそうです。サーバサイドアプリの応答が遅くて、そこそこアクセスがあるサイトとかだったら、導入を検討してみる価値があるかもしれません。
ちなみに。単純に、WordPressのキャッシュを高速に返したいのであれば、nginxのproxy_cacheで十分だと思います。。


top image from https://varnish-cache.org/