キャッシュ
キャッシュは、外部のリソースからの作成や読み込みにかかる時間を短縮するためによく使用されます。 また、高価なリソースから、安価に読み込むためにも使用されます。重いクエリーの結果やリモートの ウェブサービスへのアクセスなど変更の少ないデータは、キャッシュへの保存に適しています。 一度キャッシュに登録されたリソースを再読み込みすると、リモートのリソースへのアクセスより 高速です。
CakePHP のキャッシュは、主に Cache
クラスを使用します。 このクラスは、共通の API で全ての異なるタイプのキャッシュの実装を扱う静的なメソッドを 持っています。CakePHP は、いくつかの組込のキャッシュエンジンを用意しています。 そして、独自のキャッシュシステムを実装するための簡単な仕組みを用意しています。 以下が、組込のキャッシュエンジンです:
FileCache
File キャッシュは、ローカルファイルを使用するシンプルなキャッシュです。 最も遅いキャッシュエンジンで、アトミックな動作のための多くの機能を持ちません。 しかしながら、ディスクストレージがとても安価なので、まれに書き込まれるような 大きなオブジェクトや要素の登録にファイルがよく使われます。 2.3 以降、デフォルトのキャッシュエンジンになりました。ApcCache
APC キャッシュは、PHP の APC または APCu 拡張を使用します。 これらの拡張は、ウェブサーバー中の共有メモリーにオブジェクトを保存します。 これはとても高速で、アトミックな読み書き機能を利用することができます。 CakePHP 2.0 から 2.2 までは、(利用可能であれば) デフォルトのキャッシュになりました。Wincache
Wincache は、 Wincache 拡張を使用します。 Wincache は APC と同等の機能やパフォーマンスですが、 Windows と Microsoft IIS に 最適化しています。XcacheEngine
Xcache は、APC と同等の機能を持つ PHP 拡張です。MemcacheEngine
Memcache 拡張を使用します。 Memcache は、複数サーバに分散されたとても速いキャッシュシステムを提供し、 アトミックな操作を提供します。MemcachedEngine
Memcached 拡張を使用します。 これも memcache のインターフェースですが、より高いパフォーマンスが得られます。RedisEngine
phpredis 拡張 (2.2.3 以上) を使用します。Redis は、memcache と同様に高速で永続化した キャッシュシステムを提供し、アトミックな操作を提供します。
Changed in version 2.3
FileEngine がデフォルトのキャッシュエンジンです。以前、多くの人々にとって APC を CLI とウェブの両方での適切な設定やデプロイが困難ででした。ファイルを利用することで、 CakePHP の設定が新しい開発者にとってシンプルになりました。
Changed in version 2.5
Memcached エンジンが追加されました。そして Memcache エンジンは非推奨です。
あなたが選んだキャッシュエンンジンにかかわらず、 あなたのアプリケーションは、一貫した作法で Cache
とやり取りします。これは、あなたのアプリケーションの成長に伴い キャッシュエンジンの交換が容易であることを意味します。 Cahce
クラスに加えて CacheHelper は、ページ全体のキャッシュを行います。 これを使うと、とてもパフォーマンスが向上します。
Cache クラスの設定
Cache クラスの設定は、どこでもできます。しかし、一般的には、 app/Config/bootstrap.php
の中で Cache の設定を行います。あなたが必要なだけ、キャッシュの設定を追加できます。 そして、複数のキャッシュエンジンを利用できます。CakePHP は、2つの内部的なキャッシュの設定を app/Config/core.php
で行います。もし、 APC や Memcache を使用している場合、 コアのキャッシュにはユニークなキーをセットしておくべきです。これは、複数アプリケーションで 別のアプリのキャッシュデータを上書きしてしまうのを避けるためです。
複数のキャッシュの設定を利用することで、全てのキャッシュの設定を一元管理するのと同じくらい Cache::set()
の使用が必要になる回数を減らすことができます。 複数の設定を使用することで、必要なだけストレージを変更できます。
NOTE
どのエンジンを使用するか指定する必要があります。デフォルトで File には なりません。
例:
Cache::config('short', array(
'engine' => 'File',
'duration' => '+1 hours',
'path' => CACHE,
'prefix' => 'cake_short_'
));
// long
Cache::config('long', array(
'engine' => 'File',
'duration' => '+1 week',
'probability' => 100,
'path' => CACHE . 'long' . DS,
));
app/Config/bootstrap.php
に上記のコードを記述することで、Cache 設定が 2 つ追加されます。 'short' と 'long' という設定名で、 Cache::write()
と Cache::read()
の $config
パラメータで指定します。
NOTE
FileEndine 使用時に、正しいパーミッションでのキャッシュファイルを指定して作成するには、 mask
オプションの設定が必要です。
Added in version 2.4
デバッグモードで FileEngine 使用時には、不必要なエラーの発生を避けるため、 存在しないディレクトリは自動作成されるようになりました。
Cache のためのストレージエンジンの作成
app/Lib
内や、プラグインの $plugin/Lib
内に独自の Cache
アダプターを 用意できます。アプリケーションやプラグインのキャッシュエンジンは、コアのエンジンと 差し替えられます。 Cache アダプターは、Cache ディレクトリ内に置かなければなりません。 MyCustomCacheEngine
と名付けたキャッシュエンジンがあったとすると、 アプリケーションのライブラリとして app/Lib/Cache/Engine/MyCustomCacheEngine.php
に配置されるか、プラグインの一部として $plugin/Lib/Cache/Engine/MyCustomCacheEngine.php
に配置されます。 プラグインの Cache 設定は、ドット記法を使用する必要があります。 :
Cache::config('custom', array(
'engine' => 'CachePack.MyCustomCache',
// ...
));
NOTE
アプリケーションやプラグインのキャッシュエンジンは、 app/Config/bootstrap.php
で設定すべきです。もし、core.php にそれらの設定をしたとしても、正しく動作しません。
独自のキャッシュエンジンは、 いくつかの初期化メソッドと抽象メソッドが定義された CacheEngine
を継承する必要があります。
CacheEngine に必要な API は、以下の通りです。
class
CacheEngine
method
CacheEngine::write($key, $value, $config = 'default')
method
CacheEngine::read($key, $config = 'default')
method
CacheEngine::delete($key, $config = 'default')
method
CacheEngine::clear($check)
method
CacheEngine::clearGroup($group)
method
CacheEngine::decrement($key, $offset = 1)
method
CacheEngine::increment($key, $offset = 1)
method
CacheEngine::gc()
method
CacheEngine::add($key, $value)
クエリ結果の保存に Cache を使用
変更頻度が少ない検索結果や頻繁に読まれる題目をキャッシュの中に置くことで、アプリケーションの パフォーマンスが劇的に改善されます。 Model::find()
の検索結果が好例です。 検索結果を格納する Cache を使用するメソッドは以下のようになります。 :
class Post extends AppModel {
public function newest() {
$result = Cache::read('newest_posts', 'long');
if (!$result) {
$result = $this->find('all', array('order' => 'Post.updated DESC', 'limit' => 10));
Cache::write('newest_posts', $result, 'long');
}
return $result;
}
}
上記のコードのキャッシュの読み込みロジックを、ビヘイビアでキャッシュを読み込んだり、 関連モデルのメソッドを実行することで改善できます。改善していくことで あなたの訓練になります。
2.5 から、 Cache::remember()
を使用することで、もっとシンプルに 上記を実現することができます。 PHP 5.3 以上を使用している場合、 remember()
メソッドは、以下のように使用します。 :
class Post extends AppModel {
public function newest() {
$model = $this;
return Cache::remember('newest_posts', function() use ($model){
return $model->find('all', array(
'order' => 'Post.updated DESC',
'limit' => 10
));
}, 'long');
}
}
カウンターの保存に Cache を使用
様々な用途でカウンターをキャッシュに簡単に格納できます。例えば、コンテストで 'slots' の残りを単純にカウントダウンするために Cache に格納することができます。 Cache クラスは、簡単な方法で、アトミックにカウンターの値を増減できます。 二人のユーザーが同時にカウンターの値を下げた際、不正な値を返すような カウンターの値が競合するリスクを減らすために、アトミックな操作は重要です。
整数値をセットした後、 Cache::increment()
と Cache::decrement()
を使って操作できます。 :
Cache::write('initial_count', 10);
// Later on
Cache::decrement('initial_count');
// or
Cache::increment('initial_count');
NOTE
FileEngine では、 increment() と decrement() は動作しません。代わりに APC、Redis、Memcached を使用してください。
グループの使用
Added in version 2.2
あるグループや名前空間に属する複数のキャッシュのデータを指定したいことがあると思います。 同じグループ内の全てのエントリーで共有される情報の変更があった場合は必ず、 全体を無効化するキーが必要になります。これには、キャッシュの設定内で groups を宣言することで 可能になります。 :
Cache::config('site_home', array(
'engine' => 'Redis',
'duration' => '+999 days',
'groups' => array('comment', 'post')
));
ホームページのために生成された HTML をキャッシュに格納したいとします。そして、 コメントや投稿がデータベースに追加されるごとに、このキャッシュを自動的に無効化したい。 comment
と post
グループを追加することで、両方のグループ名を持つキャッシュの 設定に格納されたキーを効果的にタグ付けします。
例えば、新しい投稿が追加された時は必ず、 post
グループに関連する全てのデータを 削除するために、キャッシュエンジンに通知することができます。 :
// Model/Post.php
public function afterSave($created, $options = array()) {
if ($created) {
Cache::clearGroup('post', 'site_home');
}
}
Added in version 2.4
Cache::groupConfigs()
は、(例えば同一の)グループに属する設定を 取得するのに使用します。 :
// Model/Post.php
/**
* 前例の別のバリエーション。同じグループに属する全てのキャッシュを消去します。
*/
public function afterSave($created, $options = array()) {
if ($created) {
$configs = Cache::groupConfigs('post');
foreach ($configs['post'] as $config) {
Cache::clearGroup('post', $config);
}
}
}
グループは、同じエンジンで同じプレフィックスを使用している全てのキャッシュ設定間で共有されます。 もし、グループを使用していて、グループ削除をしたい場合、全ての設定に共通のプレフィックスを 指定してください。
Cache API
class
Cache
method
Cache::clearGroup($group, $config = 'default')