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=80https://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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# /etc/varnish/default.vcl | |
# This is an example VCL file for Varnish. | |
# | |
# It does not do anything by default, delegating control to the | |
# builtin VCL. The builtin VCL is called when there is no explicit | |
# return statement. | |
# | |
# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/ | |
# and https://www.varnish-cache.org/trac/wiki/VCLExamples for more examples. | |
# Marker to tell the VCL compiler that this VCL has been adapted to the | |
# new 4.0 format. | |
vcl 4.0; | |
# Default backend definition. Set this to point to your content server. | |
backend default { | |
.host = "127.0.0.1"; | |
.port = "8080"; | |
} | |
# Access control for BAN | |
acl purge { | |
"localhost"; | |
} | |
sub vcl_recv { | |
# Happens before we check if we have this in cache already. | |
# | |
# Typically you clean up the request here, removing cookies you don't need, | |
# rewriting the request, etc. | |
# BAN settings | |
if (req.method == "BAN") { | |
if (!client.ip ~ purge) { | |
return(synth(403, "Not allowed.")); | |
} | |
ban("req.url ~ /"); | |
return(synth(200, "Ban added")); | |
} | |
# Enable cookies & no cache for WordPress admin page | |
if( req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_" ){ | |
return (pass); | |
} | |
# Ignore cookies for contents | |
unset req.http.Cookie; | |
# Return Cache | |
return (hash); | |
} | |
sub vcl_backend_response { | |
# Happens after we have read the response headers from the backend. | |
# | |
# Here you clean the response headers, removing silly Set-Cookie headers | |
# and other mistakes your backend does. | |
} | |
sub vcl_deliver { | |
# Happens when we have all the pieces we need, and are about to send the | |
# response to the client. | |
# | |
# You can do accounting or modifying the final object here. | |
} |
以上で設定は完了です。
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/