【CakePHP2】キャッシュの内容を追ってみる。

【CakePHP2】キャッシュの内容を追ってみる。

山の翁が降臨してテンション上がり気味なfukasawaです。こんにちは。
酒の勢いでガチャまわして本当によかったです。

さて、少し前にCakePHP2で新しく作成されたwebサービスの不具合調査をすることがありました。修正したプログラムをデプロイしても修正が反映されないという現象です。
確認してみると、キャッシュを使うよう設定されており(CakePHP2はデフォルトでキャッシュを使うように設定されています。)そのキャッシュが残ってしまっていたのが原因のようでした。他にキャッシュを使っていない比較的小さなサービスだったのでキャッシュをオフにし、/app/tmp/cache配下に幾つか作成されていたキャッシュファイルを削除することで、とりあえず解決させたのですが、そもそもこのキャッシュって何がキャッシュされているんでしょうか。そのあたりの疑問を調査した内容について、今回は書いていこうと思います。

(最初に書いておくと、最後まで調べきれておらず中途半端なところで終わってます。すみません。)

  • 調査に使用したCakePHPのバージョンは 2.10.5 です。

キャッシュの設定を確認する。

CakePHP2.10 はデフォルトで幾つかのFile キャッシュを残すようになっています。 (File キャッシュ:webサーバ上にファイル形式でキャッシュを残すキャッシュエンジン)
このキャッシュを使うことによって、CakePHPは処理の高速化などを行っているようです。

core.phpに記載されているそのあたりの設定です。

    /**
     * Configure the cache handlers that CakePHP will use for internal
     * metadata like class maps, and model schema.
     *
     * By default File is used, but for improved performance you should use APC.
     *
     * Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
     *       Please check the comments in bootstrap.php for more info on the cache engines available
     *       and their settings.
     */
    $engine = 'File';

    // In development mode, caches should expire quickly.
    $duration = '+999 days';
    if (Configure::read('debug') > 0) {
       $duration = '+10 seconds';
    }

    // Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
    $prefix = 'myapp_';

    /**
     * Configure the cache used for general framework caching. Path information,
     * object listings, and translation cache files are stored with this configuration.
     */
    Cache::config('_cake_core_', array(
       'engine' => $engine,
       'prefix' => $prefix . 'cake_core_',
       'path' => CACHE . 'persistent' . DS,
       'serialize' => ($engine === 'File'),
       'duration' => $duration
    ));

    /**
     * Configure the cache for model and datasource caches. This cache configuration
     * is used to store schema descriptions, and table listings in connections.
     */
    Cache::config('_cake_model_', array(
       'engine' => $engine,
       'prefix' => $prefix . 'cake_model_',
       'path' => CACHE . 'models' . DS,
       'serialize' => ($engine === 'File'),
       'duration' => $duration
    ));

内容をざっくりと読み解くと、以下のような設定になっているみたいです。

_cake_core_

myapp_cake_core_ で始まる名前のFileキャッシュを/app/tmp/cache/persistent/配下に作成する(期限:999日)

_cake_model_

myapp_cake_model_ で始まる名前のFileキャッシュを/app/tmp/cache/model/配下に作成する(期限:999日)

※ただしどちらも、debugが有効の場合(本番モードでない場合)はキャッシュの有効期限は10秒になる。

コメントを読む限りだと、_cake_core_は「一般的なフレームワークのキャッシュ」、_cake_model_は「モデルやデータベースに関するキャッシュ」を残すために使用されているみたいです。

キャッシュの内容について

キャッシュに何が書き込まれるかは「Cache::write()」を使って実際にキャッシュに書き込んでいる場所を洗い出したら大体わかるんじゃなかろうか。と思ったので、CakePHPの中身をGrepしてみました(テスト系のファイルは無視しつつ…)。「_cake_core_」「_cake_model_」についての記述が見つかったのは以下のあたりです。

_cake_core_

App.php

  • キー名:file_map

    Cache::write('file_map', array_filter(static::$_map), '_cake_core_');
    

    Appクラスの変数 $_map(クラス名とそのファイルの場所の対応付けのようなもの?)をキャッシュとして保存しているみたいです。 Class App | CakePHP 2.10 $_map

  • キー名:object_map

    Cache::write('object_map', static::$_objects, '_cake_core_');
    

Appクラスの変数 $_objectsをキャッシュとして保存しているみたいです。$_objectsの中身はよくわからず。。 Class App | CakePHP 2.10 $_objects

l18n.php

  • キー名:xxx_ja (?)

    Cache::write($_this->domain, $_this->_domains[$domain][$_this->_lang], '_cake_core_');
    

l18nは多言語対応で使われるクラスなのでおそらくそれ系のキャッシュを保持してるのだと思うのですが…。

DboSource.php

  • キー名:method_cache

    Cache::write('method_cache', static::$methodCache, '_cake_core_');
    

DboSourceクラスの変数 $methodCacheをキャッシュとして保存しているみたいです。 $methodCacheにはMD5化されたキーを持つ配列が沢山入っていました。内容はモデル名・フィールド名・SELECT文の条件等 が入ってるみたいです。

Class DboSource | CakePHP 2.10 $methodCache

_cake_core_

DataSource.php

  • キー名:method_cache

    Cache::write($key, $data, '_cake_model_');
    

DBのテーブル名が配列でズラッと入ってるみたいです。

さて、このあたりのキャッシュがそれぞれどういった役割を果たしているのか確認していきたいのですが……

(◜◡◝)  ヨウワカラン。

キャッシュなので、いずれも高速化等のために保存しているのだと思うのですが、細かくなにをやっているのかまではよくわからず。
時間切れなので、中途半端ですが今回はこのあたりで……。(ほぼ何も判明していないような。)CakePHPは自分の知らないところでもいろいろ頑張ってくれてるみたいです。

キャッシュをオフにする

↓のコメントアウトを外すことでキャッシュを残さないように設定することもできます。

app/Config/core.php

    //Configure::write('Cache.disable', true);

また、できてしまったキャッシュを消すときはCache::clear() メソッドを呼ぶことで消すことができます。

上の方にも書いたのですが、デバッグレベル:0(本番モード)でなければ10秒ほどしかキャッシュを残さないようになっているみたいなので、キャッシュは有効にしておいて、本番デプロイをしたタイミングでキャッシュを消してあげるのがよさそうです。

  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ