![]() |
![]() |
|
||
![]() |
|
|||||||||||||||||||||||||||||||||||||||||
| [19 апреля 2008 г.] |
|
Сегодня мы поговорим о работе с кэшем и технологии тэгирования кэша на примере системы memcached. Технические подробности и библиотеку, поддерживающую тэги в memcached, вы найдете в соответствующей статье Конструктора: Dklab_Cache: правильное кэширование — тэги в memcached, namespaces, статистика.
Работа с типичной кэширующей системой (в том числе с memcached) заключается в выполнении трех основных операций:
Предположим, мы хотим эакэшировать долгий SQL-запрос для быстрого отображения части страницы. В этом случае мы проверяем: имеется ли запись в ячейке кэша, соответствующей этому запросу. Если ячейка пуста, данные загружаются из СУБД и сохраняются в кэш для возможных будущих извлечений.
| Листинг 1: Типичная работа с кэшем |
if (false === ($data = $cache->load("key"))) {
$data = executeHeavyQuery();
$cache->save($data, "key");
}
display($data); |
К сожалению, в чистом виде этот подход удается применять не так часто. Дело в том, что данные в БД могут измениться, и мы должны каким-то образом очистить ячейку кэша, чтобы пользователь увидел результаты этих изменений немедленно. Можно использовать метод remove() с указанием ключа, однако во многих случаях в момент обновления данных мы просто не знаем, в каких именно ячейках они кэшируются.
Проблема, на самом деле, гораздо сложнее. В высоконагруженных системах данные добавляются в таблицы по нескольку (сотен) раз в секунду. Поэтому логика отслеживания зависимостей и проверки, какие ячейки кэша нужно очищать, а
Тэгирование предоставляет решение этой проблемы. Каждый раз, когда данные записываютя в некоторую ячейку кэша, мы помечаем их
Давайте модифицируем предыдущий пример с использованием тэгов. Предположим, что SQL-запрос существенно зависит от ID текущего пользователя $loggerUserId, поэтому каждому такому пользователю выделяется отдельная ячейка с именем "key_{$loggedUserId}". Однако данные зависят и от ID другого человека $ownerUserId, чей профиль просматривает текущий пользователь. В этом случае мы можем пометить ячейку тэгом, связанным с пользователем $ownerUserId:
| Листинг 2: Тэгирование кэша |
if (false === ($data = $cache->load("key_{$loggedUserId}"))) {
$data = loadProfileFor($loggedUserId, $ownerUserId);
$cache->save($data, "key_{$loggedUserId}", array("profile_{$ownerUserId}");
}
display($data); |
Теперь, если меняются данные в профиле пользователя $ownerUserId (например, человек поменял свое имя), нам достаточно дать команду на очистку тэга, связанного с этим профилем:
| Листинг 3: Очистка тэга |
$cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array("profile_{$ownerUserId}"); |
Обратите внимание, что кэш-ячейки всех остальных пользователей при этом не пострадают: очистятся только те, которые зависели от $ownerUserId.
Собственно, фраза "пометить ячейку C тэгом T" означает то же, что утверждение "ячейка C зависит от данных, описанных как T".
В PHP работа с memcached поддерживается отдельным модулем memcache. В нем есть все необходимые операции и методы, однако интерфейс модуля слишком низкоуровневый, чтобы применять его в скриптах. Отличное решение представляет Zend Framework: в нем работа с кэшем четко структурирована и разнесена по уровням абстракции. Именно на основе интерфейсов из Zend Framework работает подсистема Dklab_Cache_Backend, описанная в статье Dklab_Cache: правильное кэширование — тэги в memcached, namespaces, статистика.
В Zend Framework подсистема кэширования разнесена на два логических блока:
Backend-классы обычно не используют напрямую, вместо этого применяют frontend-классы. Для каждого frontend-класса можно использовать совершенно любой backend-класс: это достигается благодаря единому интерфейсу backend-кэширования.
Самое приятное и удивительное в Zend_Cache то, что его интерфейсы изначально включают поддержку тэгов! Например, метод save() имеет следующий прототип:
Теперь вы знаете, что такое тэгирование и как оно помогает при разработке сложных проектов. Если вам понравилось, переходите к верхней части стати Конструктора Dklab_Cache: правильное кэширование — тэги в memcached, namespaces, статистика и попробуйте предлагаемые решения на практике. В помощью библиотеки Dklab_Cache вы сможете использовать технологию тэгирования ключей на своем сайте.
Ну а
![]() |
| ||||||||||||||||||||||||||||
| Дмитрий Котеров | 19 апреля 2008 г. ©1999-2010 | | Контакт | Вернуться к оглавлению |