チェ・ゲバムラの日記

脱犬の道を目指す男のブログ

【CakePHP2.x】キャッシュによるパフォーマンス改善 ~CakePHP2実践入門「15章」~

パフォーマンス計測してボトルネックを探す

ボトルネックの調査

計測方法

Xdebug、XHProfなどが代表的だが少し慣れがいるのと、PHP拡張インストールも必要なため、
簡易的に実行時間を記録するBenchmarkコンポーネントを作成、利用する方法もある。

public $components = array('Benchmark');

有効にするとapp/tmp/logs/bench.logというファイルにログ出力される。

計測用アプリケーションを作る

Slowコントローラー
Slowモデル
Slowビュー
を作成。
doSomethingメソッドでsleep(5)を実行して5秒処理を停止。
この状態でアクセスすると擬似的にパフォーマンスが遅くなっているのを再現できる。

パフォーマンス計測する

SlowコントローラーでBenchmarkコンポーネントを指定する。

doSomethingメソッドの前後にmarkメソッドを記述して時間を記録する。
ここまでで計測準備完了。

ブラウザからアクセスするとログが記録される。
そこで最初のログは読み込み時なので0.000208秒
次のログはSlowコントローラー読み込み後(2つめのmarkメソッド)で5.002154秒
となっていたら、Slowコントローラーがボトルネックだということがわかる。

Cacheクラスを使ったパフォーマンス改善

キャッシュを利用して改善

キャッシュとは

ボトルネック改善方法2つ
1.ボトルネックの処理を変更
効果は絶大だが工数が多くかかる、不具合がでるリスクあり。

2.キャッシュ利用
ボトルネック処理は遅いまま、同じ処理をキャッシュから取り出して利用する。
手軽に導入でき、不具合がでるリスクは少ない。

キャッシュの設定

app/Config/core.phpにデフォルトという設定を記載する例。

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

※第一引数:任意の設定名を記載
※第二引数:キャッシュの設定を連想配列で記載

キャッシュの読み書き操作時に設定名を指定することで適用される。

1時間の場合

>|php|
Cache::config('hour' , array(
'engine' => 'File',
'duration' => '+1 hour',
));
|

1日の場合
>|php|
Cache::config('day' , array(
'engine' => 'File',
'duration' => '+1 day',
));
|

キャッシュクラスの操作

キャッシュの読み書きを汎用的に行うクラス。
使用方法は読み込むのみ。
App::uses('Cache','Cache');

書き込み

writeメソッドで3つの引数を指定する。
第一引数:キャッシュ認識するキー
第二引数:キャッシュする値
第三引数:キャッシュの設定(省略時はdefaultが指定される)

Cache::write($key, $value, $config = 'default');

読み込み

readメソッドで2つの引数を指定。
第一引数:キャッシュ読み込む対象のキー
第二引数:キャッシュの設定(省略時はdefaultが指定される)

存在しない、有効期限切れ、エラー時はfalseが戻り値。

$value = Cache::read($key , $config = 'default');

削除

deleteメソッドで2つの引数を指定。
第一引数:キャッシュ削除する対象キー
第二引数:キャッシュの設定(省略時はdefaultが指定される)

Cache::delete($key , $config = 'default');

Cacheクラスを実際に使ってみる

設定

AppクラスのusesメソッドでCacheクラス読み込み。
次にdoSomethingメソッドでキャッシュ読み込み。


キャッシュが存在すればキャッシュの値を返して処理終了。
キャッシュが存在しなければ処理を続行する。

slowモデル
>|php|
App::uses('Cache','Cache');

class Slow extends AppModel{
public $useTable = false;

public function doSomething(){
$ret = Cache::read('Slow_something');
if($ret != false){
return $ret;
}
//何かの処理
sleep(5);

$ret = array('time' => date('Y:m:d H:i:s'));
Cache::write('Slow_something', $ret);

return $ret;
}
}

|

キャッシュのログで動作確認

ブラウザで2回アクセスする。

1回目は現在時刻が表示。
2回目は1回目と同じ時刻が表示される。

ログ
/app/tmp/logs/bench.log
にて確認できる。

ビューキャッシュを使ったパフォーマンス改善

ビューに特化したキャッシュ。
Cacheクラスはアプリケーションで記述必要だが
設定すればコード不要でキャッシュ操作してくれるので手軽。

ビューキャッシュ有効化

デフォルトでは無効のため、下記の行をコメント外す。
app/Config/core.php
Configure::write('Cache.check',true);

次にコントローラーの$helpersプロパティにCacheヘルパーを指定。
public $helpers = array('Cache');

ビューキャッシュ設定

コントローラーで行う。
$cacheActionプロパティに設定を連想配列で指定する。

indexアクションを1時間、viewアクションを10分間キャッシュする例。
public $cacheAction = array(
'index' => '+1 hour',
'view' => '+10 minute',
);

コントローラー中の全アクションに指定する場合はキーを指定しない。
public $cacheAction = array('+1 day');

一部分をビューキャッシュ対象から除外

下記のようにするのみ。

キャッシュして欲しくない箇所

ビューキャッシュ削除

削除されるケース3つ
・有効期間を経過した場合
・モデルのsaveメソッド、deleteメソッドを実行した場合
・clearCache関数を実行した場合

有効期限切れ

そのビューキャッシュを出力する際、自動でキャッシュ削除される。
ビューキャッシュ出力されないままアクションが実行される。
その後、設定に応じてキャッシュ生成される。
Configure::read('Cache.check')がtrueの時のみ実行。

モデルのsaveメソッド、deleteメソッドを実行した場合

自動でビューキャッシュ削除される。
Slowモデルのsaveメソッド実行すると、Slowコントローラーのビューキャッシュが削除される。
ただしroutes.phpでルーティング変更している場合は削除されないことがある。
Configure::read('Cache.check')がtrueの時のみ実行。

clearCache関数を実行した場合

任意でビューキャッシュを削除できる。
Slowコントローラーのビューキャッシュを削除する場合は下記。
clearCache('slow');

全てのビューキャッシュ削除する場合は下記。
clearCache();

ビューキャッシュを実際に使う

設定

core.phpでビューキャッシュを有効にする。
次にSlowコントローラーで設定。

>|php|
class SlowController extends AppController{
public $helpers = array('Cache');
public $cacheAction = array('index' => '+1 hour');
}
|

動作確認

ブラウザから2回アクセス。
2回目では1回目の時刻が表示される。
app/tmp/logs/bench.logを確認。
2回目のログは記録されてない。
これは出力するキャッシュが存在する場合、アプリケーション実行せずにキャッシュの出力のみ行う。
これによりパフォーマンス改善される。
※ただしデバッグレベル1以上にするとフッタに実行時間が記録される。(ソースの表示より)