[WordPress] KUSANAGIのbcacheとfcacheの使い分け(2)

2020/10/22WordPress

KUSANAGIのbcacheとfcacheの使い分けの続き。追加調査したところ、前回よりさらに良い設定が見つかったのでメモ。

このサイトでは高速化の手段としてnginxのfastcgi cache (fcache)と、KUSANAGIのbcacheを利用していた。Wordpressは重たい(遅い)CMSなので、キャッシュを使わないとレスポンスが悪化する。遅くなると、せっかく見に来てくれた方を待たせることになる。しかもTTFB(Time To First Byte)が遅いと、Google検索の表示順位が下がるという説もある。

キャッシュなしでは数100msかかる処理が、キャッシュヒットした場合は0ms-10msで処理が完了する。なるべくキャッシュを使いたいのだが、「キャッシュ==古いデータを見せる」なので、キャッシュの有効期限はあまり長くしたくない。

動作の説明

前回の繰り返しになるが、キャッシュの動作原理から説明する。

fcacheはnginx、bcacheはWordpressプラグインがキャッシュ動作を行う。fcacheはWordpressの起動処理が不要なので、高速に応答を返せる(fcache HIT)。fcacheにデータが残っていない場合、bcacheにヒットすれば100ms程度で応答を返せる。両方失敗するとWordpressはページ生成を行う。これには数100msかかる。



上記動作の問題点

いつまでも古いデータを見せるわけにはいかないので、キャッシュには有効期限を設定する。bcacheの有効期限が過ぎるとWordpressのページ生成が発生し、クライアントは数100ms待たされる。有効期限が1時間程度の場合、人気の無いページ(1日に数回以下のアクセス)は、毎回ページ生成が発生する。これは遅過ぎる。

前回記事(KUSANAGIのbcacheとfcacheの使い分け)では、これを避けるためにfcache 20分、bcache 記事詳細は3時間の設定にしたが、それでも人気のない場末ページは毎回fcacheミスが発生し、100ms〜数100ms待たされていた。

そうは言っても、fcacheのキャッシュ有効期限を長くし過ぎるといつまでも古いページが表示される。キャッシュにはなるべくヒットさせたいが、キャッシュ内容はなるべく新しくしたいのだ。

  • 誰かがアクセスしないと、キャッシュが更新されない(→ アクセス数の少ないページはいつまでも更新されない)。
  • キャッシュが古いと判明した時点で更新動作が発生する(→ 更新するまでブラウザに返答を返せない)。

nginxの設定で改善

下の2行をnginx.confに追加してみた。use_staleとbackground_updateを組み合わせることで、キャッシュの有効期限が過ぎていてもそれを利用し、バックグラウンドで更新を行う。同時に要求がきた場合は1つだけwordpressに渡し、残りは待たされる。うちのサイトでは同一コンテンツに同時にアクセスが来ることはまず無いのでlockしているが、アクセス多数のところは検討が必要だろう。

fastcgi_cache_use_stale error timeout invalid_header updating;
fastcgi_cache_background_update on;
fastcgi_cache_lock on;

こうなると、もはや bcache は必要がない。今のところkusanagiはbcacheのためだけに使っているので、kusanagiごと外してしまった方が良いかもしれない。

bcacheを外すことで、cacheの動作はシンプルになった。



これらの設定については A Guide to Caching with NGINX and NGINX Plus – NGINX が参考になる。proxy_ で始まっている部分は fastcgi_ に読み替える。

nginx logのSTALEはキャッシュ更新時間を含んでいるようだ

さて、上述の設定を行っても nginx のログに記録される応答時間は短くならない。うちのサイトだと MISSもSTALEも同じぐらいの時間がかかる(100-150msぐらい)。
どうやら nginxログに記録されている時間はキャッシュ更新終了までの時間のようで、クライアントからみた応答時間ではないようだ。

0.153 STALE – (略) “GET / HTTP/1.1" 200 29153 “-" “curl/7.29.0" “-"
0.000 HIT – (略) “GET / HTTP/1.1" 200 29153 “-" “curl/7.29.0" “-"

curlを使ってTTFBを測ると、STALEもHITも短い時間で応答が返ってくるので、意図したように動作しているようだ。

$ curl https://example.com/ –dump-header /dev/stderr -s -o /dev/null -w '%{time_starttransfer}\n’
HTTP/1.1 200 OK
Server: nginx
(中略)
X-Cache: STALE

0.047

$ curl https://example.com/ –dump-header /dev/stderr -s -o /dev/null -w '%{time_starttransfer}\n’
HTTP/1.1 200 OK
Server: nginx
(中略)
X-Cache: HIT

0.056


キャッシュ保持時間をどう設定すべきか

上述の設定では、キャッシュ有効期限は短くても良い。有効期限を過ぎていてもキャッシュがあればそれを返す。

応答時間を速くしつつ新しいコンテンツを返すために、High Availability Content Caching with NGINXNginx: Async Cache Refresh – Divyendu's Blogでは、有効期限を短く(秒単位)にしている。

アクセスが少ない場末のページの場合は、fastcgi_cache_pathで指定した保持期間が過ぎればキャッシュは破棄され、キャッシュミスが発生する。公開サイトであれば、検索エンジンが周回してくるのでキャッシュ更新をそれに任せる手はありそうだ。周回間隔よりも長い保持時間を設定しておけば良さそうな気がする。1日ぐらい?

結論:bcache要らないよね

私の用途では nginxのキャッシュだけで足りるので bcache は不要になりました。そうなるとkusanagiの機能は翻訳アクセラレータだけ使っているので、別プラグインに置き換えてkusanagiプラグインは消した方が良さそう。nginxやphp-fpmの更新は便利なので、uninstallまではしませんが。

WordPress

Posted by ず@沖縄