fbpx

メニュー

ほんとうは怖いWP Super Cacheの話

高橋文樹 高橋文樹

この投稿は 12年 前に公開されました。いまではもう無効になった内容を含んでいるかもしれないことをご了承ください。

WordPressで一般ユーザーのログインを伴うサイト(ECサイト、SNSなど)を作っている方も多いと思いますし、そういった依頼を受けることも多いのですが、最近「バグです!」という報告を受けてよくよく調べたらWP Super Cacheというキャッシュプラグインのせいだったということがなんどかありました。毎回説明するのが大変なので、書いておきます。

そもそもWP Super Cacheはどういう仕組みか

通常のWebサイトというのは、ユーザーから求められたリクエストからPHPなりRubyなりPythonなりが求められるデータを推測し、データベースに対して適切な操作を行い、最終的にHTMLを書き出します。

動的なサイトがリクエストを受け取って処理する仕組み
動的なサイトがリクエストを受け取って処理する仕組み

で、Webサイトが重くなる原因(ボトルネック)は色々あると思うのですが、てっとり早い方法はキャッシュです。キャッシュというのは、一定の処理結果に名前をつけておき、それを保存しておくことです。このキャッシュのスコープ(どこからどこまでをキャッシュするか)には色々ありますが、WP Super Cacheの場合、WordPressが行う処理すべてをキャッシュします。

WP Super CacheはWordPressの処理をスキップする
WP Super CacheはWordPressの処理をスキップする

これは劇的な効果を生みますが、方法としてはかなり大雑把ですので、問題も当然発生します。それは、「どのユーザーが見ても同じ情報になってしまう」ということです。コメントを投稿したのに、そのコメントがページに反映されていなかったら、「あれ?」っとなってしまいますよね。それどころか、投稿編集画面で投稿を保存しても保存されなかったりしてはそもそもブログの運営ができなくなります。

もちろん、WP Super Cacheはそれなりに作り込まれたプラグインなので、こうした問題を避けるために以下のようなデフォルト設定を行っています。

  • 管理画面( http://example.com/wp-admin 以下)はそもそもキャッシュしない
  • キャッシュには有効期限を設定する
  • コメントを投稿した直後のユーザーにはキャッシュを提供しない(=自分のコメントが投稿された後のページが表示される)

他にも色々と工夫はありますし、設定も変えられるのですが、デフォルトでは通常のブログ記事として利用する限りは最適化されるようになっています。この、「通常のブログ記事としては」というのがポイントです。みなさん、日経新聞のサイトを見るときでもなければ、Webサイトを見るためにログインしないですよね。でも、AmazonやFacebook、Twitterを見る場合はほとんど必ずログインしています。WordPressというのは基本的にブログサイト用のCMSなので、ECサイトやSNSは想定していないわけですね。

どんな問題が発生しうるか

さて、このキャッシュ系プラグインの利用の仕方によっては、サイトの存続に関わる重要なサービス上の不備が発生しえます。怖いですね〜。

ケーススタディ1. Twitterみたいなサイトなのに投稿できない

WordPressで会員制サイトを作っていて、ユーザーが投稿できる機能を作っていたとしましょう。WordPressで管理画面以外から投稿させる機能を作るとかを参考にしてください。

ここでWP Super Cacheを使っていると、「投稿したにも関わらず、自分の投稿は反映されない上、同じ投稿フォームが表示される」という悲劇が起こります。本来なら投稿を保存して「投稿が保存されました」などとメッセージを表示すべきだったページがキャッシュを返すことで処理をスキップしてしまうのです。

これはそもそもWebサイトが提供するはずだった機能を提供できていないので、Webサービスとして体をなしていないですね。怖いですね〜。

ケーススタディ2. ECサイトで購入履歴ダダ漏れ

ちょっと前にメッセサンオーでエロゲー購入履歴が晒されて阿鼻叫喚という事件がありましたが、購入履歴ページというのは個人の履歴に紐づく重要なページです。

で、たとえばWooCommerceというECプラグインを例に挙げると、購入履歴情報は http://example.com/my-account というURLで表示されます。ここでWP Super Cacheを何も考えずに有効化していると、「ユーザーAの購入履歴がユーザーBの購入履歴として丸見え」というとんでもない事件が発生します。

これはサイト存続に関わる大問題なので、くれぐれも起きないようにしたいですね。会社だったら潰れてもおかしくないですよ。ちなみに、WordPressのECプラグインWelcartでもキャッシュでひでぶした事例は報告されています。怖いですね〜。

ログインしているユーザーにキャッシュを提供しなければよい?

すでに述べた通り、WP Super Cacheには「既知のユーザーにはキャッシュを提供しない」という項目があるので、これを使えばよいような気もしますが、ケース・バイ・ケースです。

項目自体はちゃんとあります
項目自体はちゃんとあります

そもそもWP Super Cacheの基本的な理念は「ブログ記事は誰が見ても同じだから、全部キャッシュしちゃえば超早いじゃん」です。開発者に尋ねたわけでもないのに、言い切ります。

どのようなサイトかにもよりますが、ほとんどのユーザーがログインしているようなサイトにおいてページキャッシングはあまり意味を持ちません。ログインユーザーが増えれば増えるほど、キャッシュを提供する機会が少なくなっていくからです。

他にも特定のUserAgentに別のキャッシュを提供したり、特定のURLをキャッシュ対象から除外したりできますが、基本的にはサイト構成によってどこまで負荷をトレードオフするかという判断を求められます。ここで「こうやっておけばOK」という例を提示することは難しいです。

キャッシュは結構難しい

キャッシュには色々な方法があり、WordPressのプラグインでは以下のものがあります。

  • WP Super Cacheのようにページ全体をキャッシュするもの(W3 Total Cacheなど)
  • データベースをキャッシュするもの(DB Cache Reloaded
  • WordPressのObject Cache機能を拡張するもの(Memcached Object Cacheなど。まあ、ほとんどの共有サーバにMemcachedは入ってませんが)

他にもWordPress自体に備わっているキャッシュ機能があり、たとえばTransient APIなどがそうです。これは「Twitterの最新ステータスを取得して表示する」といった場合に有効ですね。僕もWP-HamazonというAmazonのアフィリエイトリンクを生成するプラグインで使ってます。

上記の他にもNginxによるProxy Cacheや先述したMemcachedなど、WordPressに限らずWebサイト全般で使えるキャッシュ技術があります。こういうのはサーバにミドルウェアをインストールして使うので、LINUX系OSの基本的な知識(yumとか./configure make make installとか)が求められます。

また、キャッシュはデバッグが難しかったりする(問題の再現性が低い)ので、うまく運用するには高度な知識が求められます。

以前mixiがMemcachedのバグでうんたらかんたらというニュースがありましたが、CookpadやDeNAとかでも会員制サイトでうまくキャッシュするために優秀なエンジニアが日々努力しているというのが現状ではないでしょうか。

ではどうすべきか

ここで「なぜそもそもWP Super Cacheを使おうと思ったか」ということに立ち返ってみましょう。それは、ページの表示速度を上げたかったからではないでしょうか。下記のような代替案を試してください。

1. サーバを引っ越す

サイトをどのようにマネタイズしているかによりますが、サーバ代金はメチャクチャ安くなっているので、ここが問題になることはあまりないでしょう。ロリポップじゃないと赤字になるECなんて閉鎖してしまった方がいいです。

サーバの引越しは大変面倒ですが、どのサーバでもきちんと動くようにポータブルなサイト作りを普段から心がけましょう。ノマドサイトですね。

2. CDNで静的ファイルの配信負荷を減らす

Cloud Flareとか無料のもありますし(参考:SSLありのWordPressだけど高速化したいからCloudFlareのCDNを無料で使う)、最近はDigital CubeさんからWP Boosterというのも出ました。CDNについてはおググりください。

3. プラグインを検証する

データが2000万件とか、同時セッション2万とかでない限り、サイトが信じられないぐらい遅くなるのは大抵PHPの問題です。プラグインやテーマ内での特定の処理が変なので遅くなっているのです。これを一つ一つあたっていくのは面倒くさいですが、学ぶことも多いです。

結論

  • キャッシュってそんなに簡単な技術じゃない
  • WP Super Cacheを使いたいのではない、サイトの表示を早くしたいのだ

以上です。

[429] [429] Client error: `POST https://webservices.amazon.co.jp/paapi5/getitems` resulted in a `429 Too Many Requests` response: {"__type":"com.amazon.paapi5#TooManyRequestsException","Errors":[{"Code":"TooManyRequests","Message":"The request was de (truncated...)

[429] [429] Client error: `POST https://webservices.amazon.co.jp/paapi5/getitems` resulted in a `429 Too Many Requests` response: {"__type":"com.amazon.paapi5#TooManyRequestsException","Errors":[{"Code":"TooManyRequests","Message":"The request was de (truncated...)

[429] [429] Client error: `POST https://webservices.amazon.co.jp/paapi5/getitems` resulted in a `429 Too Many Requests` response: {"__type":"com.amazon.paapi5#TooManyRequestsException","Errors":[{"Code":"TooManyRequests","Message":"The request was de (truncated...)

すべての投稿を見る

高橋文樹ニュースレター

高橋文樹が最近の活動報告、サイトでパブリックにできない情報などをお伝えするメーリングリストです。 滅多に送りませんので、ぜひご登録お願いいたします。 お得なダウンロードコンテンツなども計画中です。