AmazonSimpleAdmin にキャッシュを適用させる話 をただいま進めてるとこですが、その前に、そもそも WordPress のキャッシュって何よ、ていう話を書いてみます。
WordPress でキャッシュと呼ばれてるものには、実は以下の二種類があります。
- ページ出力結果をキャッシュしておくもの
- MySQLの検索結果など途中のデータをキャッシュしておくもの
この二つが結構紛らわしい。前者のキャッシュ用ドライバは一般に advanced-cache.php というファイル名で実装されるですが、後者のキャッシュにも Advanced Cache plugin という名前のついるものがあったりして、どうもいかん (しかも後者のやつは Automattic 謹製だぜよ、それってどうよ)。
ここでは、前者をページキャッシュ、後者をオブジェクトキャッシュと呼ぶことにします。私が今即席でつけた名前なので国際的には全く通用しません。公式サポートフォーラムでこの名前で質問して「はぁ?」とか言われても当局は一切関知しないのでそのつもりで。
ページキャッシュ
まずページキャッシュから行きましょう。ページキャッシュは WordPress 本体には無い機能で、plugin によって提供されます。1 Blog Cacher, WP-Cache, WP Super Cache などがあります。
いずれも、ページ出力をファイルに落としてディスク上に保存しておくことで性能向上を図ります。1ページが1ファイルになります。キャッシュがヒットしたときは、WordPress 本体はほとんど働かずにキャッシュファイルの内容をそのままブラウザに出力します。ユーザ毎に出力を変えたい場合はそれだと困るので、例えば認証 cookie を持っていたらキャッシュの例外とする、みたいな形で対応します。また、キャッシュがヒットした場合は stattraq や statpress などでアクセス情報を取れません。MovableType における静的生成に近い感じになるわけですな。
ページキャッシュ用の plugin は一般に wp-content/advanced-cache.php というファイルをインタフェースとして提供されます。plugin 本体は wp-content/plugins 以下に置かれますが、それに加えて advanced-cache.php ファイルを置く、あるいは symlink を貼る必要があります。
オブジェクトキャッシュ
ページキャッシュとは別にオブジェクトキャッシュがあります。ページキャッシュは1ページを1ファイルとしてキャッシュしますが、オブジェクトキャッシュは PHP の変数を1個としてキャッシュします。変数を処理してページを作る手間はかかるので、ページキャッシュに比べるとやはり負荷が残りますが、動的生成のままで負荷を減らせるのは魅力。
オブジェクトキャッシュは WordPress 2.0 以降に標準でついてる機能です。これにより WordPress 1.* 時代よりも処理性能が理論的には向上することになってます。例えば、1.* 時代には blog のタイトルを表示するにも、毎回 MySQL を検索して blog title を引っ張ってきていました。2.* では、一度取得した blog title は、オブジェクトキャッシュの中に保存されるため、キャッシュが期限切れになるまでは MySQL を引かずに済み、それにより処理性能が速くなる、っつう建前です。
なんですが、実際にはいろいろと問題があり、WordPress 2.* でのオブジェクトキャッシュはデフォルトで無効になっています。
どこに問題があるかっつうと、そのキャッシュされたデータがどこに保存されるか、です。保存方法はいくつかあります。
WordPress 本体に内蔵されているオブジェクトキャッシュでは、ディスク上にファイルとして保存されます。wp-config.php に define(ENABLE_CACHE, true);
という一行を付け加えると、ファイルでのオブジェクトキャッシュが有効になります(キャッシュファイルは wp-content/cache ないし wp-content に書き出される)。なんですが、MySQLにアクセスするのとディスク上のファイルをアクセスするのだと、どっちが速いって結構微妙です。オブジェクトをシリアライズするオーバーヘッドもあるし、状況によってはかえって遅くなることも。そのため、デフォルトでは無効になっています。
共用のレンタルサーバなどで MySQL が混みあっていて重い場合には、オブジェクトキャッシュを有効にすることで一定のパフォーマンス向上が期待できます。
しかし、ファイル以外のところに保存するオブジェクトキャッシュ plugin もいくつか開発されており、素晴らしい性能を発揮するするものもあります。
Rauru Blog では XCache のオブジェクトキャッシュ を使ってます。XCache は PHP アクセラレータの一種で、共有メモリを使ってデータをキャッシュする機能を持ってます。共有メモリはファイルの読み書きに比べて圧倒的に高速で、実際 サーバ負荷低減に素晴らしい効果 がありました。もしサーバが XCache に対応してるなら、是非とも入れるべきです。
XCache を使う上でトレードオフとなるのは、メモリの消費量です。php.ini の中で XCache の variable cache に割り当てるメモリ量を設定します。ここのメモリ割り当てが少ないと、データがキャッシュに収まり切らずにすぐ無効になってしまうので、あまり効果が期待できません。しかしメモリを取り過ぎると、apache 自体が苦しくなってしまうでしょう。物理メモリはいくらあっても足りませんなあ。
PHP アクセラレータには XCache 以外にも eAccelerator てのもあり、こっち用の plugin も用意されています。こっちは試したこと無いんですが、たぶん同じような性能を発揮してくれると思います。
また memcached を使う plugin もあります。memcached はソケット経由でデータをやり取りするキャッシュデーモンで、サーバが複数台に分散している際に威力を発揮します。これが使われるのは WordPress MU などで大掛かりなホスティングサービスを提供する場合だけでしょうな。
オブジェクトキャッシュの問題は、明示的にオブジェクトキャッシュを使うようなコードの書き方をしなきゃならんとこです。全てのデータが自動的にキャッシュされるわけではありません。
WordPress 2.3.2 では、まあそこそこのデータがキャッシュされてはいるんですが、WordPress のコードを眺めてみると、これもキャッシュすれば絶対高速化するのにと思うようなデータがキャッシュされてないっつうコードもあちこちに残ってます。特に wp_get_archives()
がキャッシュしてないっつうのは許せねえ。WordPress 2.4 ではもっとキャッシュするコードを増やす とアナウンスされてるので (On many page loads you will see zero queries
とか大口叩いてるぞ)、XCache/eAccelerator が使えるサーバだと結構快適になりそうで楽しみ。
plugin も同じです。残念なことに、多くの plugin はオブジェクトキャッシュを使うように作られてません。使えば絶対軽くなるのになー。AmazonSimpleAdmin とかな。今後の対応が望まれるー。
オブジェクトキャッシュ用の plugin は、wp-content/object-cache.php というファイルで提供されます。wp-content/plugins の下に置くわけでは無い点に注意してください。
February 20th, 2008 at 15:36
WordPressのオブジェクトキャッシュを有効化する方法…
わかってはいたことですがロリポップのMySQLが遅いので、デフォルトで無効化されているWordPressのオブジェクトキャッシュ機能を有効化する手順等を調べました。
(1)wp-config.phpでENABLE_CAHC…