ビューキャッシュ導入(1)

ビューキャッシュ導入(途中経過)時の追加・変更点と、効果について。

導入方法は概ね各種サイトの情報通りですが、設定ファイルでキャッシュの有効期限を設定できるようにしました。



キャッシュ効果

キャッシュ導入により、約1.3回/秒だったアクションの出力が、7.6回/秒になりました*1

キャッシュ導入前

[cake@cake chara-shee]$ ab -n 10 -c 10 http://hogehoge/characters/view/1
(中略)
Requests per second: 1.27 [#/sec] (mean)

キャッシュ導入後

[cake@cake chara-shee]$ ab -n 10 -c 10 http://hogehoge/characters/view/1
(中略)
Requests per second: 7.58 [#/sec] (mean)

基本導入方法

参考サイト
http://www.sylvan-l.net/b/2008/01/04/cakephp12%E3%81%A7cache%E3%82%92%E4%BD%BF%E3%81%8A%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E3%81%A8/

ソース

+++ b/app/config/core.php
-       //Configure::write('Cache.check', true);
+       Configure::write('Cache.check', true);

+++ b/app/controllers/app_controller.php
@@ -43,6 +43,7 @@ class AppController extends Controller
            $helpers= array(
                'Html',
                'Form',
+               'Cache',


$this->cacheActionは各コントローラで、配列を用いてアクション毎に設定します。
http://book.cakephp.org/ja/view/346/Caching-in-the-Controller


設定ファイルでConfigureに設定した値は、メソッド外では使用できないため、beforeFilterでセットします。

+++ b/app/config/conf/config.php
@@ -16,6 +16,22 @@ Configure::write('User.Password.Length',
+/*
+ * キャッシュ
+ */
+// キャッシュの最大有効期限(秒)
+Configure::write('Cache.expire', 7 * 24 * 3600);
+// キャッシュを作成しない(常に最新の情報を表示しますが、動作が遅くなる場合があります)
+Configure::write('Cache.disable', false);
+// キャッシュの詳細設定
+Cache::config('default', array(
+       'engine' => 'File', //保存方法
+       'duration'=> Configure::read('Cache.expire'),
+       'probability'=> 100, // 期限切れキャッシュの更新率
+       'path' => CACHE, // Fileの保存パス
+       'prefix' => 'cake_',
+       'serialize' => true,
+));

+++ b/app/controllers/characters_controller.php
@@ -8,6 +8,8 @@ class CharactersController extends AppController {

+       var $cacheAction = array();
+
(中略)
        function beforeFilter() {
                parent::beforeFilter();

+               // Cache
+               $this->cacheAction = array(
+                       'index' => Configure::read('Cache.expire'),
+                       'view/' => Configure::read('Cache.expire')
+               );
+
ログイン前後で一部表示が異なる場合

ログイン有無など条件で表示が変わる箇所などは、普通にキャッシュすると、キャッシュを作成した状態のデータしか表示されなくなります。


あらかじめテンプレートに、

で、キャッシュしない箇所を指定しておきます。

ログインの有無は、usersコントローラに確認用のアクションを追加して、都度そこを読み込むようにしました。

+++ b/app/views/layouts/default.ctp
<ul>
+<cake:nocache>
+<?php
+$user = $this->requestAction('/users/get_user');
+echo $this->element('pc_mainnav', array(
+       'user' => $user,
+));
+?>
+</cake:nocache>
</ul>

/users/に作成したget_userは、ログイン中のユーザ情報$this->userを返すものです。*2

+++ b/app/controllers/users_controller.php
@@ -48,6 +49,7 @@ class UsersController extends ModuleController {
                parent::beforeFilter();

                // 認証なしアクセス可
+               $this->AuthPlus->allow('get_user');

@@ -59,6 +61,10 @@ class UsersController extends ModuleController {
        }

+       function get_user() {
+               return $this->user;
+       }
+


Benchmarkコンポーネントによると、get_user()の出力に掛かる時間は0.05秒。
ApachBenchの情報から、高速化によるメリットは十分そうです。

2010-07-07 16:18:12 Debug: [6b63091d] 0.00001 : <==construct :
2010-07-07 16:18:12 Debug: [6b63091d] 0.00635 : users/get_user: beforeFilterStart :
2010-07-07 16:18:12 Debug: [6b63091d] 0.03853 : users/get_user: afterFilterStart :
2010-07-07 16:18:12 Debug: [6b63091d] 0.05287 : <==destruct :


views/elements/pc_mainnav.ctpは、$user有無で表示を切り替える内容になっています、

<?php if (CorePlus::is_valid($user, 'User.id')): ?>
	<li><?php echo $html->link(__('Home', true), Configure::read('Routing.basePath')); ?>

	<li><?php echo $html->link(__('Characters', true), array('controller' => 'characters', 'action' => 'index')); ?></li>

<?php if (!$site_configs['System.singleSystem']['value']): ?>
	<li><?php echo $html->link(__('Systems', true), array('controller' => 'systems', 'action' => 'index')); ?></li>
<?php endif; ?>

	<li><?php echo $html->link(__('Users', true), array('controller' => 'users', 'action' => 'listview')); ?></li>
<?php endif; ?>

<?php if (CorePlus::is_valid($user, 'User.id')): ?>
	<li><?php echo $html->link(__('Configuration', true),  array('controller' => 'users', 'action' => 'edit', $user['User']['id'])); ?>
<?php endif; ?>

<li>
<?php if (CorePlus::is_valid($user, 'User.id')): ?>
<?php echo $html->link(__('Logout', true), array('controller' => 'users', 'action' => 'logout')); ?>
<?php else: ?>
<?php echo $html->link(__('Login', true), array('controller' => 'users', 'action' => 'login')); ?>
<?php endif; ?>
</li>

参考サイト
ASTRODEO 株式会社アストロデオ

*1:ApacheBench測定&自分比

*2:app_controllerで設定