Memcached в PHP Kohana и его тестировние

в 13:26, , рубрики: Kohana, php, Программирование

Уже много описано про 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 — установлена блокировка ключа
Н — успешный запрос кеша

То есть, наш кеш прекрасно работает.

Ну и результат до и после кеширования:

image

Как видно, довольно таки тяжелая страница с множеством обращений к базе грузится за 0,455 сек. против 1,7 сек. до кеширования

Скачать Memcacheimp.php можно здесь.

Автор: navikom

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js