もふもふ技術部

CakePHPでSQLの結果をキャッシュしてみる


概要

CakePHPでSQLの実行結果をキャッシュしておいて、更新されるまでは再検索しないような動きをさせたくなったので少し調べてみたけど、正解がわからないまま強く当たって流れで押し出された感じのメモ。

下記ページを参考にした。
http://book.cakephp.org/2.0/en/core-libraries/caching.html

キャッシュの種類

参考URLによると、キャッシュには以下のもの等が用意されているそうな。

  • FileCache(ファイルにキャッシュする。遅い)
  • ApcCache(Alternative PHP Cacheを使う)
  • Wincache(Wincacheを使う)
  • MemcacheEngine(Memcacheを使う)

今回の用途的にはApcCacheを使っておけば良いだろうか。速くてアトミックなRead/Writeもできる子らしい。

入ってない場合は入れておく。

ApcCacheを使ってみる

とりあえずキャッシュの設定をする。下記のように記述すれば良いらしい。書いた内容はapp/Config/bootstrap.phpあたりに入れておく。

上記は最低限の記述で、「Apcで1日キャッシュしておくよ」と書いているつもり。

次にModelにキャッシュを使ったfind機能っぽいものを書く。

これで1日はキャッシュされたままになる。

DBに変更があった場合にキャッシュをリロードしたい時は、どう書くのが良いのだろう。とりあえずModelのafterSaveとafterDeleteでキャッシュ消す処理でも入れておこうかと思った。

でも、この書き方だと一貫性とかどうなるんだろうと思って調べてみたところ、ApcCacheはプロセス間でキャッシュが共有されるわけではないらしい。ということは複数プロセスで動いていた際に、別プロセスのキャッシュは更新されない気がする。

キャッシュ時間を1分くらいに設定して「反映まで1分待ってね」で済ますか、諦めて別のキャッシュを使うか。

MemcacheEngineを使ってみる

memcachedならプロセス間通信も問題ない。わざわざMemcache入れなくても運用とかどっかファイルのタイムスタンプでも使って問題を回避できそうな気もするけど、男は度胸、何でも試してみよう。

とりあえずmemcachedのインストール。CentOSの場合。

自動起動するようにしたいので、下記のコマンドを打つ。

再起動して起動してるか確認。

起動していたら、次はPHPのmemcached用モジュールを入れる。

memcached用のモジュールとして「php-pecl-memcache」と「php-pecl-memcached」(後ろにdが付く)があるらしい。CakePHPでは「php-pecl-memcache」(dがない方)を使うようだ。違いに気づかずハマった。両者がどう違うかは未調査。

さっき、app/Config/bootstrap.phpに書いていた設定をMemcached風に変更。

これで動くようになった、かと思いきや、permission deniedで怒られる。CentOSなんで、SELinuxに引っかかっているらしい。

一旦、無効になっていただいて実行したらうまく通った。

でも、止めちゃうのはやり過ぎだよね、ということで探してみたところ、httpd_can_network_memcacheがfalseになってるのがいけないんじゃね、という指摘を見かける。ということで、下記コマンドを実行。

で、SELinuxさんに復帰してもらう。

これで動いた。あとはAfterSaveとAfterDeleteでキャッシュをクリアしておけば、だいたい思ったような動きになるような気がする。本当に無事動くかは未検証。

The following two tabs change content below.
masato watanabe

masato watanabe

もふもふ部ブレーン。プログラマ兼ライター。