Elementキャッシュ
ホームなど、ポータル系の画面で
新着情報エリア
自分の情報エリア
RSS情報エリア
・・・などのように更新タイミングが分かれている場合は、Elementキャッシュがよいようです。
Elementキャッシュ導入で、参考にしたのは以下。
http://text.tklabo.net/blog/8/view-cache
Elementキャッシュ導入で、表示が1.4回/秒から、3.9回/秒に向上しました*1
A:ユーザ表示
B:自分の新着
C:全体の新着
で、Cのみログイン/未ログインを問わず、全員で共通表示します。
A/B/Cを、それぞれElementキャッシュしました。
ポイントは、 A/Bは、キャッシュ名(key)にセッションIDをいれた点です。
B(Aも同様)
echo $this->renderElement('character_picture_table', array(
'header' => sprintf(__("%s's Characters", true), $target_user['User']['name']),
'characters' => $target_user_characters,
(中略)
+ 'cache' => array(
+ 'time' => time() + Configure::read('Cache.expire'),
+ 'key' => $session->id(),
+ )
));C
echo $this->renderElement('character_picture_table', array(
'header' => __('Latest Characters', true),
'characters' => $public_characters,
(中略)
+ 'cache' => array(
+ 'time' => time() + Configure::read('Cache.expireShort'),
+ 'key' => null,
+ )
));オプションパラメータに $options['cache']['key']を指定すると、キャッシュファイル名が
element_[key]_[エレメントファイル名]
となります。
keyにセッションIDを入れることで、それぞれのユーザごとに
「ホーム用自分の新着」キャッシュを持たせる事ができます。
実際のキャッシュファイル作成状態
キャッシュが無い状態で、未ログインユーザがアクセス。
[cake@cake chara-shee]$ ls -l app/tmp/cache/views/
合計 44
まず、Cのキャッシュができます。
ここから、ユーザ1でログイン。
[cake@cake chara-shee]$ ls -l app/tmp/cache/views/
合計 44
- rw-r--r-- 1 apache apache 3163 7月 16 15:15 element__character_picture_table
- rw-r--r-- 1 apache apache 2800 7月 16 15:21 element_ekg7u0r93oa1j486f1k99mkpe7_character_picture_table
- rw-r--r-- 1 apache apache 295 7月 16 15:21 element_ekg7u0r93oa1j486f1k99mkpe7_home_left
- rw-rw-r-- 1 cake cake 0 7月 13 15:05 empty
ユーザ1用のA/Bのキャッシュが作成されます。
この時、Cは更新されてないのがポイント。
さらに、別窓からユーザ2でアクセスすると、ユーザ2用のキャッシュが別途作成されます。
[cake@cake chara-shee]$ ls -l app/tmp/cache/views/
合計 44
- rw-r--r-- 1 apache apache 3163 7月 16 15:15 element__character_picture_table
- rw-r--r-- 1 apache apache 2800 7月 16 15:21 element_ekg7u0r93oa1j486f1k99mkpe7_character_picture_table
- rw-r--r-- 1 apache apache 295 7月 16 15:21 element_ekg7u0r93oa1j486f1k99mkpe7_home_left
- rw-r--r-- 1 apache apache 2868 7月 16 15:23 element_l6o3bnorfrm87r1nsdlnlm4sa5_character_picture_table
- rw-r--r-- 1 apache apache 319 7月 16 15:23 element_l6o3bnorfrm87r1nsdlnlm4sa5_home_left
- rw-rw-r-- 1 cake cake 0 7月 13 15:05 empty
仕上げに、ユーザ情報の更新/削除/ログアウトがあった場合のキャッシュ削除を入れて完成*2。
ソース差分抜粋
app/models/app_model.php
+
+ /* キャッシュ削除 */
+ // ホーム関連
+ function deleteCacheHome()
+ {
+ $this->deleteCacheLastCharacters();
+ $this->deleteCacheAnonymousHome();
+ $this->deleteCacheMyHome();
+ }
+
+ // 最近更新されたキャラクター
+ function deleteCacheLastCharacters()
+ {
+ @unlink(CACHE.'views'.DS.'element__character_picture_table');
+ }
+
+ // 未ログインホーム
+ function deleteCacheAnonymousHome()
+ {
+ @unlink(CACHE.'views'.DS.'element__home_right');
+ }
+
+ // マイホーム
+ function deleteCacheMyHome()
+ {
+ $Session = CorePlus::set_behavoir('Session');
+
+ if (!$Session->id()) {
+ return false;
+ }
+
+ @unlink(CACHE.'views'.DS.'element_'.$Session->id().'_character_picture_table');
+ @unlink(CACHE.'views'.DS.'element_'.$Session->id().'_home_left');
+ }
+
}
app/models/behaviors/session.php
@@ -0,0 +1,27 @@
+<?php
+class SessionBehavior extends CakeSession {
+ function setup(&$Model,$config = array()){
+ $base = null;
+ $start = Configure::read('Session.start');
+ extract($config);
+
+ $session = null;
+ if(ClassRegistry::isKeySet('CakeSession')){
+ $session = ClassRegistry::getObject('CakeSession');
+ }else{
+ App::import('Core','CakeSession');
+ $session = new CakeSession($base,$start);
+
+ ClassRegistry::addObject('CakeSession',$session);
+ }
+
+ $Model->Session = $session;
+ if($start && !$Model->Session->started()){
+ $Model->Session->start();
+ }
+ }
+
+ function id($id = null) {
+ return parent::id($id);
+ }
+}
app/models/user.php
@@ -135,6 +135,16 @@ class User extends AppModel {
{
return parent::beforeSave($options);
}
+ function afterSave($created) {
+ $this->deleteCache4User();
+
+ return parent::afterSave($created);
+ }
+ function afterDelete() {
+ $this->deleteCache4User();
+
+ return parent::afterDelete();
+ }
@@ -156,4 +166,13 @@ class User extends AppModel {
return parent::betweenWrapper($check[0], $idLength['min'], $idLength['max']);
}
+
+ /* キャッシュ削除 */
+ function deleteCache4User()
+ {
+ // Home
+ $this->deleteCacheHome();
+ }
+
+
}
app/views/elements/home_right.ctp
@@ -17,7 +17,10 @@
'action' => 'index',
$target_user['User']['id'],
),
-
+ 'cache' => array(
+ 'time' => time() + Configure::read('Cache.expire'),
+ 'key' => $session->id(),
+ )
));
?>
<?php endif; ?>
@@ -37,7 +40,10 @@
'controller' => 'characters',
'action' => 'index'
),
-
+ 'cache' => array(
+ 'time' => time() + Configure::read('Cache.expireShort'),
+ 'key' => null,
+ )
));
?>
app/views/users/index.ctp
@@ -1,14 +1,23 @@
<div id="home" class="layout2colums users view">
<?php
-if (!empty($user['User']['id'])) {
- echo $this->renderElement('home_left', array(
- 'user' => $user,
+$key = null;
+
+if ($user['User']['id']) {
+ $key = $session->id();
+
+ echo $this->element('home_left', array(
+ 'target_user' => $user,
'owner' => true,
+ 'cache' => array(
+ 'time' => time() + Configure::read('Cache.expire'),
+ 'key' => $key,
+ )
));
}
*1:ApacheBench測定。向上の度合いは内容や環境によります
*2:モデルでセッション情報の取得は、http://d.hatena.ne.jp/hiromi2424/20100203 を参考にしました
