Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Dklab_Cache: правильное кэширование — тэги в memcached, namespaces, статистика (Дмитрий Котеров)
Goto page Previous  1, 2
Author Message
Валенок
Участник форума



Joined: 06 Apr 2006
Posts: 520
Карма: -3
   поощрить/наказать


PostPosted: Sat Oct 24, 2009 6:34 pm (написано за 5 минут 23 секунды)
   Post subject:
Reply with quote

У меня 2 вопроса:
Во-первых, я еще не начинал использовать Dklab_Cache_Frontend_Slot, но судя по коду, он всё сам сериалайзит. Это значит, что мне стоит отключить automatic_serialization в Zend_Cache?
Как-то это не очень подходит к принципу "добавил обертку - ничего больше не менял", хотя, может, я и ошибаюсь )

Во-вторых, как думаете, может стоит сделать кеширование результатов кеширования (масло масленное) в член класса? Я тут посмотрел на Memcached: "109 запросов за 0.034423589706421 секунд." и расстроился %)

(апдейт)
Вот, если интересно кому-нибудь:
Code (php): скопировать код в буфер обмена
<?
class R00_Cache_Slot_Abstract extends Dklab_Cache_Frontend_Slot {
        protected static (www.php.net/static) $_hereCache = array (www.php.net/array)();
        protected $id = null;

        protected function _getBackend() {
                return Zend_Registry::get('Cache')->getBackend();
        }
       
        public function __construct($obj, $value = false, $lifetime = false) {
                if ($obj instanceOf R00_Model_iUnique) {
                        $this->id = $obj->getResourceId() . '_' . $value; // для кеширования "отдельных кусков", типа post_15_comments
                } else {
                        $this->id = $obj; // тогда это строка-индекс для кеширования
                        $lifetime = $value; // только 2 аргумента
                }
               
                if (!$lifetime)
                        $lifetime = 3600*24;
               
                parent::__construct($this->id, $lifetime);
        }
       
        public function load($callback = false) {
               
                if (!isset (www.php.net/isset)(static (www.php.net/static)::$_hereCache[$this->id]) || (static (www.php.net/static)::$_hereCache[$this->id] === false)) {               
                        static (www.php.net/static)::$_hereCache[$this->id] = parent::load();
                        if (static (www.php.net/static)::$_hereCache[$this->id] === false && $callback) {
                                $this->save( $callback() );
                        }
                }
                return static (www.php.net/static)::$_hereCache[$this->id];
        }
        public function save($data) {
                static (www.php.net/static)::$_hereCache[$this->id] = $data;
                parent::save(static (www.php.net/static)::$_hereCache[$this->id]);
        }
        public function remove() {
                unset (www.php.net/unset)(static (www.php.net/static)::$_hereCache[$this->id]);
                parent::remove();
        }
}
Насчет $callback: работает так (php > 5.3):
Code (php): скопировать код в буфер обмена
                $slot = new Cлот;
       
                $table = self::_getTable();
       
                $object = $slot->load(function() use($id, $table) {
                        return $table->getById($id);
                });
В тыщу раз удобнее if-а :)
Back to top
View user's profile Send private message
Миржан
Заглянувший



Joined: 28 Oct 2009
Posts: 1
Карма: 0
   поощрить/наказать


PostPosted: Wed Oct 28, 2009 11:09 am (спустя 3 дня 16 часов 34 минуты; написано за 7 минут 53 секунды)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
jurm
Это несовместимость с новой версией Zend Framework, похоже. Потому что в ней объявление этого метода такое:

    public function setBackend(Zend_Cache_Backend $backendObject)

А было -

    public function setBackend($backendObject)

На самом деле, это полный беспредел, потому что в классе Zend_Cache_Backend завязки за файловую систему и вообще всякий мусор, который в мемкэш-бакенде совершенно не нужен. Куда только катится ZF...
Как я понял, разработчики ZF не собираются этот баг исправить(framework.zend.com/issues/browse/ZF-8139).
Пробовал наследовать Zend_Cache_Backend так:
class Dklab_Cache_Backend_TagEmuWrapper extends Zend_Cache_Backend implements Zend_Cache_Backend_Interface
но там иногда выходить ошибка:
Class 'Zend_Cache' not found in <b>/library/Zend/Cache
/Core.php</b> on line <b>345
Как быть?
Back to top
View user's profile Send private message
Артём Макаров
Заглянувший



Joined: 27 Jun 2007
Posts: 2
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Tue Dec 22, 2009 7:30 pm (спустя 1 месяц 25 дней 8 часов 20 минут; написано за 3 минуты 5 секунд)
   Post subject:
Reply with quote

Здравствуйте, Дмитрий.

Кажется, я нашел довольно жирный баг в методе Dklab_Cache_Backend_NamespaceWrapper::multiLoad(). Дело в том, что если в обернутом им бекенде есть метод multiLoad(), то будет вызван последний, причем в него будут переданы ключи с уже приделанным пространством имен, и, соответственно, возвращены будут записи в ассоциативном массиве с неправильными (с пространством имен) ключами.

Cтроки 43-45 в Dklab/Cache/Backend/NamespaceWrapper.php:
Code (php): скопировать код в буфер обмена
if (method_exists (www.php.net/method_exists)($this->_backend, 'multiLoad')) {
    return $this->_backend->multiLoad($this->_mangleIds($ids), $doNotTestCacheValidity);
}
Это не страшно, когда Dklab_Cache_Backend_NamespaceWrapper используется в качестве самого верхнего декоратора, однако кеширование перестает работать, если использовать библиотеку так, как указано в листинге 6 (dklab.ru/lib/Dklab_Cache/#list6) - нужные ключи просто не находятся в возвращенном массиве. Возможный метод решения проблемы следующий: надо заменить указанный выше код на:
Code (php): скопировать код в буфер обмена
if (method_exists (www.php.net/method_exists)($this->_backend, 'multiLoad')) {
    $saved = $this->_backend->multiLoad($this->_mangleIds($ids), $doNotTestCacheValidity);
    $result = array (www.php.net/array)();
    foreach ($ids as $id) {
        $mangledId = $this->_mangleId($id);
        if (isset (www.php.net/isset)($saved[$mangledId])) {
            $result[$id] = $saved[$mangledId];
        }
    }
    return $result;
}
В таком случае все начинает работать как положено.


Кроме того, есть предложение использовать магическую константу __FUNCTION__ вместо __METHOD__ в бекенде Dklab_Cache_Backend_Profiler - это уберет "очевидный" кусок 'Dklab_Cache_Backend_Profiler::' из второго параметра callback'а.
Back to top
View user's profile Send private message
Guest






Карма: 387
   поощрить/наказать


PostPosted: Fri Feb 05, 2010 2:08 pm (спустя 1 месяц 13 дней 18 часов 38 минут; написано за 19 секунд)
   Post subject:
Reply with quote

Артём Макаров, да, действительно листинг 6 не работает.
Back to top
Guest






Карма: 387
   поощрить/наказать


PostPosted: Sat Nov 13, 2010 11:57 pm (спустя 9 месяцев 8 дней 9 часов 48 минут; написано за 26 секунд)
   Post subject:
Reply with quote

У меня своя Аналогичная библиотека
----
А все что связано с ZF не особо терплю ...
Back to top
cybexx
Заглянувший



Joined: 01 Jul 2010
Posts: 1
Карма: 0
   поощрить/наказать


PostPosted: Mon Apr 23, 2012 8:54 am (спустя 1 год 5 месяцев 9 дней 8 часов 56 минут)
   Post subject:
Reply with quote

Помогите с проблемой. Или направьте на пусть верный...

Есть простой код:
Code (php): скопировать код в буфер обмена
$frontendOptions = array (www.php.net/array)(
       'lifetime' => 600,                   
       'automatic_serialization' => false
    );

$memcachedOptions = array (www.php.net/array)(
  'servers' => array (www.php.net/array)(array (www.php.net/array)('host' =>'127.0.0.1'))
);


    $cache = Zend_Cache::factory('Core',
                                 'Memcached',
                                 $frontendOptions,
                                 $memcachedOptions);

$result = 'This is string for cache!';
$cache->save($result, 'myresult');

$r = $cache->load('myresult');
var_dump (www.php.net/var_dump)($r);
Запускаю. Все отрабатывает нормально. На экран получаю:
Code (php): скопировать код в буфер обмена
string(26) "This is string  for cache!"
Сразу же комментирую строку:
Code (php): скопировать код в буфер обмена
// $cache->save($result, 'myresult');
 
Запускаю. Получаю:
Code (php): скопировать код в буфер обмена
bool(false)
Почему теряется кеш?
Back to top
View user's profile Send private message Send e-mail
newartix
Guest





Карма: 387
   поощрить/наказать


PostPosted: Thu May 03, 2012 7:58 am (спустя 9 дней 23 часа 4 минуты; написано за 1 минуту 35 секунд)
   Post subject: Поддержка разных процедур инвалидации
Reply with quote

Не очень понятно. В рамках Zend_Cache тэги поддерживаются только для $oCache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,...) ? Остальные процедуры инвалидации (NOT_MATCHING_TAG, MATCHING_ANY_TAG) не поддерживаются?
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Fri Jun 22, 2012 1:01 am (спустя 1 месяц 18 дней 17 часов 2 минуты; написано за 34 секунды)
   Post subject:
Reply with quote

newartix
Совершенно верно. Их достаточно сложно реализовать в рамках используемого алгоритма (да и сам этот алгоритм тоже не так уж и прост сам по себе).
Back to top
View user's profile Send private message Send e-mail
OLzenizin
Заглянувший



Joined: 01 Nov 2012
Posts: 1
Карма: 0
   поощрить/наказать

Location: Россия Москва

PostPosted: Thu Nov 01, 2012 3:13 pm (спустя 4 месяца 10 дней 14 часов 12 минут)
   Post subject:
Reply with quote

каким образом гарантируется, что тэги не протухнут раньше тэгируемых?
Back to top
View user's profile Send private message
ink
Участник форума



Joined: 05 Apr 2004
Posts: 136
Карма: 7
   поощрить/наказать


PostPosted: Wed Feb 11, 2015 10:37 am (спустя 2 года 3 месяца 9 дней 19 часов 24 минуты; написано за 4 минуты 22 секунды)
   Post subject:
Reply with quote

Встала задача оптимизировать memcached, в первую очередь ввести теги.

Поиски привели к Dklab_Cache.
Смущает дата релиза... Может есть развитие библиотеки или подскажете достойных конкурентов?

И может у кого есть реализация фикса стаи собак(dog-pile)?
Не хочется велосипед изобретать :)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Goto page Previous  1, 2
Page 2 of 2    Email to a Friend.
Post a reply
Username
Subject
Господа спамеры и оптимизаторы!

Вы можете даже и не пытаться вставлять в текст поста ссылки - они все равно автоматически удаляются (вернее, тэги <a> заменяются на тэги <u>).

Но если не поверите и все же попытаетесь - как только увидите, что все безрезультатно, удалите свой пост, пожалуйста. Модераторы тоже люди, нехорошо, если они погрязнут в тоннах спама.
     

Disable BBCode in this post
Disable Smilies in this post
    HTML is OFF
BBCode is ON
Smilies are ON
You cannot post new topics in this forum. You can reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML