cacheの置き場はtmpのままが良い?

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
これはキャッシュじゃなくてスマッシュです……か?

この記事を三行にまとめると

キャッシュファイルの保存先を変えたい
無理に保存先をいじる必要なんてないんじゃないの?
キャッシュファイルを同期するやり方って、どうなの?
CakePHPの話なんですが、Cakeさんは、これといった余計な設定をしない場合、勝手にデータベースの構造とかをtmpフォルダの下にある「cache」というフォルダに保存してくれます。

この保存先を変えたい。そんなときはどうすれば良いのか。

バージョンによって多少違うかもしれないんで、ここではCakePHPのバージョンが「2.3.10」の場合でいきますね。ただ、ちゃんとは動作確認してないけど、ソースを見る限りでは「2.5.2」も同じ感じっぽい。



core.phpの設定

core.phpを見ると、下の方に……ってか一番下にこんなことが書いてあります。

Cache::config('_cake_core_', array(
  'engine' => $engine,
  'prefix' => $prefix . 'cake_core_',
  'path' => CACHE . 'persistent' . DS,
  'serialize' => ($engine === 'File'),
  'duration' => $duration
));

Cache::config('_cake_model_', array(
  'engine' => $engine,
  'prefix' => $prefix . 'cake_model_',
  'path' => CACHE . 'models' . DS,
  'serialize' => ($engine === 'File'),
  'duration' => $duration
));

これがキャッシュの設定です。この「path」のところで保存先を設定してます。ちなみに上記のコードにある「CACHE」ってのはCakePHPが用意した定数で、echoしてみれば分かりますが「・・・/app/tmp/cache」という、tmpの下にあるcacheフォルダまでの絶対パスが定義されてます。

例えばこれを、appフォルダの直下にcacheフォルダを作ってそこに保存したければ、こうですね。

Cache::config('_cake_core_', array(
  'engine' => $engine,
  'prefix' => $prefix . 'cake_core_',
  'path' => APP . 'cache' . DS . 'persistent' . DS,//ここを変更
  'serialize' => ($engine === 'File'),
  'duration' => $duration
));

Cache::config('_cake_model_', array(
  'engine' => $engine,
  'prefix' => $prefix . 'cake_model_',
  'path' => APP . 'cache' . DS . 'models' . DS,//ここを変更
  'serialize' => ($engine === 'File'),
  'duration' => $duration
));

「CACHE」ってなってたところを「APP . ‘cache’ . DS」に変えました。「APP」っていうのもCakePHPが用意した定数で、appフォルダまでの絶対パスが定義されてます。

これでバッチオッケー……と思いきや。



bootstrap.phpの設定

もう一つ、bootstrap.phpの方にも設定が必要らしいのです。

bootstrap.phpを見ると、こんな一行がある。

Cache::config('default', array('engine' => 'File'));

こっちにも保存先を書いてやらないといけないらしい。省略するとデフォルトの設定(tmpの下にあるcacheフォルダを見に行こうとする)が反映されてしまうみたい。

Cache::config('default', array(
  'engine' => 'File',
  'path' => APP.'cache'.DS,
));

これでapp直下にあるcacheフォルダの方を見に行ってくれます。保存先をもっと全然違う場所にしたければ、このpathのところを任意に書き換えればオッケー牧場ひげ工場。



保存先を変えたいってどんなときさ?

無理に保存先をいじる必要なんてないんじゃないの? って言われたらその通りだと思うんですけど、じゃあどんなときに保存先を変えたいのか。

こっからは質問みたいな感じなんですけど、例えばロードバランサーを使って二台のサーバーでウェブサービスを公開してる場合。その二台はlsyncdを使って同期を取ってるとする。

lsyncdの説明はここでは省略しますが、とりあえずそれを使うと同期するディレクトリを任意に指定できる。Cakephpのappフォルダ以下を同期するとかね。僕もそんな感じの設定をやってるんですが、でもtmpの下は同期の対象から外してるんですよ。あそこはエラーログとか、あとは同期する必要のない一時ファイルなんかを置いとくために使ってるから、変に同期されても困るので。

でもこの設定だと、コントローラーやモデルは同期元のサーバーの方でだけファイルを更新やら削除すれば同期先にも反映されますが、tmpの下にあるキャッシュファイルは、同期元を削除しても同期先のサーバーには残ったままになってしまいます。

データベースにカラムを追加したり、そういう変更があったときには、キャッシュファイルを消すことがありますよね。でもそのたびに手動で複数のサーバーのキャッシュファイルを消すのって面倒じゃん? うっかり一台のサーバーだけ消し忘れとかあったら、やばいじゃん? だから他のファイルと一緒で、同期元の方で消したら他も自動で削除されてほしいじゃん?

lsyncdの設定でtmpの下のcache以外を同期の対象外にするように設定すれば良いっちゃ良いんですけど、でもそこをごちゃごちゃ書き換えるよりは、上記のようにキャッシュファイルの置き場を変更して同期の対象にさせちゃった方が楽そうなんですよね。



ってことで、今回の設定に考えが至ったわけですよ。

ただ、キャッシュファイルをサーバー間で同期するって、普通そういうことやるんですかね。何となく違和感があるような……?

やっぱりロードバランサーを使うときは、キャッシュサーバーみたいなのを別に用意して、MemcachedやらAPCやらを使って管理するのが良いんでしょうか。でもMemcachedって使ったことないからよく分からないんですよね。あとAPCって何だ?

上記の対応方法が一番簡単そうだから、特に問題ないんなら、ひとまずはこれで良いかなーと思うんですけど、どうなんでしょう?






まあ、サーバーの同期うんぬんってのは完全に僕の個人的な事情なのでいいとして、とりあえずキャッシュファイルの置き場所を変えたいのなら、core.phpとbootstrap.phpをちょちょっと書き換えればできます。

必要があればお試しあれ〜。






追記(2015/02/27)

別な方法でキャッシュファイルの削除を同期してみました。

テキストファイルをbashコマンドで
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください