[Из песочницы] Memcached в PHP Kohana и его тестировние
Уже много описано про memcache, однако я помучался прежде чем нашел оптимальный вариант для одного проекта на PHP, достаточно ресурсоемкого с большим объемом расчетов в Kohana.Memcache пришлось отфутболить сразу же, так как когда ключей набегает пару сотен, нереально отследить, когда и какой ключ нужно убить. Смотрел в сторону MemcacheTag, где применено использование тэгов для объединения нескольких ключей, однако он оказался слишком сырым и весьма неудобным для работы. В конце концов был найден самый, на мой взгляд, оптимальный вариант работы с memcached.
Описание принципа работы данной технологии лучше всего посмотреть здесьили на первоисточнике.
Я же напишу как подключать и использовать в фреймворке Kohana, каким образом отследить ключи кэшей и собственно протестировать как работает кэширование в проекте.
Итак, начнем: В bootstrap раскомментировать 'cache'=> MODPATH.'cache', добавить файл MODPATH/cache/classes/Cache/Memcacheimp.phpвот такого вида:
class Cache_Memcacheimp extends Kohana_Cache_Memcacheimp {} Добавить файл MODPATH/cache/classes/Kohana/Cache/Memcacheimp.php.
Ниже файл для скачивания.
Скопировать MODPATH/cache/config/cache.php, вставить его в application config и добавить туда, как последний элемент массива, следующий код:
'memcacheimp' => array ( 'driver' => 'memcacheimp', 'default_expire' => 3600, 'compression' => FALSE, 'servers' => array ( 'local' => array ( 'host' => 'localhost', 'port' => 11211, 'persistent' => FALSE, 'weight' => 1, 'timeout' => 1, 'retry_interval' => 15, 'status' => TRUE, ), ), 'instant_death' => TRUE, 'statistics' => FALSE, ) где установлены стандартные элементы по умолчанию для кэширования, кроме ключа 'statistics', который я добавил для тестирования. Он включает и выключает тестирование нашего memcached.
Все теперь можно работать.
Вызов метода:
Model_SomeClass: factory ('table')→get ($id, 'key_tag'); где key_tag — объеденяющий тег для нескольких ключейСоздаем объект:
$this→cache = Cache: instance ('memcacheimp'); Таким образом, создаем cache в модели:
public function get ($id, $tags = null) { $cOne = $this→cache→get («get_{$this→_table}_{$id}»);
if (! is_array ($cOne)) { $query = DB: query (Database: SELECT, «SELECT * FROM $this→_table WHERE id='$id'»);
$cOne = $query→execute ()→as_array (); $this→cache→set («get_{$this→_table}_{$id}», $cOne, array ($tags)); } return $cOne; } Так убиваем cache c ключами объедененными тегом key_tag:
$this→cache→delete_tag ('key_tag'); Чтобы убить весь cache или удалить по ключу, пользуемся стандартными методами cache, так как наш класс наследуется от Cache.
Для того, чтобы проследить процесс работы нашего кеширования и понять, какие ключи у нас создаются, изменим немножко конфиг:
'statistics' => TRUE, Теперь мы можем посмотреть, что происходит с нашим кэшем. Открываем APPPATH/cache/statistics/ и смотрим содержимое файла get_someTable_someId.txt, где get_someTable_someId — имя нашего ключа.
содержимое файла: MLWHHHHH
М — кэш отсутствуетL — установлена блокировка ключаН — успешный запрос кеша
То есть, наш кеш прекрасно работает.
Ну и результат до и после кеширования:
Как видно, довольно таки тяжелая страница с множеством обращений к базе грузится за 0,455 сек. против 1,7 сек. до кеширования
Скачать Memcacheimp.php можно здесь.
