Memcached в PHP – просто с Zend Framework

zend frameworkПрименение Memcached для улучшения быстродействия ваших приложений может быть сделано довольно быстро без использования Zend Framework. Если вам нужен только Memcached, пропустите часть про Zend Framework (и, по всей видимости, всю статью). С другой стороны, если вы используете Zend Framework, но не используете Memcached, эта статья поможет вам начать это делать. Но, в любом случае: Если вы до сих пор не используете Memcached, начинайте прямо завтра.

Что такое Memcached

Вот определение, взятое непосредственно с сайта Memcached: «Memcached это быстродействующая система объектного кэширования распределенной памяти». Другими словами, Memcached помогает вам увеличить быстродействие приложения за счет кэширования данных в памяти. Использование Memcached для загрузки данных вместо базы данных или файловой системы может существенно повлиять на быстродействие вашего приложения. Самое классное то, что польза возрастает с повышением нагрузки, а стало быть, вы улучшаете возможность масштабирования.

Краткий обзор Zend_Cache

До того как мы продолжим рассматривать Memcached в ZF, важно понимать, каким образом кэширование представлено в Zend_Cache. В Zend_Cache, вы должны настраивать «стратегию» frontend (Zend_Cache_Frontend) и «двигатель» backend (Zend_Cache_Backend). Каждый кэшируемый объект должен иметь backend и frontend.
Двигатель backend это как раз то, о чем вы думаете: метод, который используется Zend_Cache для хранения кэшированных данных. На данный момент Zend Framework использует такие backend’ы: File, SqlLite, XCache, Memcached, Apc и Zend Platform. Есть еще один backend, называемый «TwoLevels», который может хранить данные в быстром или медленном backend’е, в зависимости от приоритета. (Я, в общем-то, не очень осведомлен, как это работает и зачем вам это нужно).
Стратегия frontend заботится о двух вещах: проверка истечения срока действия и способа реализации кэширования. Например, вы можете применять Zend_Cache_Frontend_File к данным кэша до тех пор, пока определенный файл не будет изменен. Пример из жизни – кэширование примера Zend_Config_Xml до тех пор, пока XML-файл, на который он указывает, не будет изменен. Самая простая frontend-стратегия это Zend_Cache_Core, которая просто говорит: «скажи мне что кэшировать и когда должен истечь срок действия этого». Zend_Cache_Core это то, что мы будем использовать в нашем примере.

Реализация с Zend Framework

Первое, что следует сделать – это установить наш объект кэширования. Как вы догадались, Zend Framework реализует Memcached через Zend_Cache_Backend_Memcached. Я решил, что Zend_Cache_Core наиболее удобен для первого запуска в моих приложениях, я советую и вам начать именно с него.
array( array(
'host' => '127.0.0.1',
'port' => '11211'
) ),
'compression' => true
) );
// настраиваем логер кэширования
$oCacheLog = new Zend_Log();
$oCacheLog->addWriter( new Zend_Log_Writer_Stream( 'file:///tmp/pr-memcache.log' ) );

// настраиваем стратегию frontend кэширования
$oFrontend = new Zend_Cache_Core(
array(
'caching' => true,
'cache_id_prefix' => 'myApp',
'logging' => true,
'logger' => $oCacheLog,
'write_control' => true,
'automatic_serialization' => true,
'ignore_user_abort' => true
) );
// составляем объект кэширования
$oCache = Zend_Cache::factory( $oFrontend, $oBackend );

Здесь мы создали новый пример Zend_Cache_Core (frontend) и Zend_Cache_Backend_Memcached, которые используют Zend_Log для логирования.
Настройка Zend_Cache_Backend_Memcached:
servers
Список серверов, разделенных запятыми, которые должна использовать данная сущность.
compression
Определяет, должны ли данные быть сжаты до того как они будут записаны.
Настройки Zend_Cache_Core:
caching
включение кэширования. Это удобно, если вы хотите оставить переключатель включен/выключен для исключение кэширования из процесса. В моих приложениях, я передаю здесь переменные Zend_Config.
cache_id_prefix
Это значение, которое будет подставляться перед id (индексом) каждого кэшированного объекта.
logging
Это включает логирование для данного backend. Вы должны указать logger в опции `logger`, которая описана ниже.
logger
Это должна быть сущность Zend_Log, которую вы хотите использовать для логирования.
write_control
это выполняет постоянную проверку, когда какие-либо данные пишутся в кэш. Это безопасней, но медленней.
automatic_serialization
Включение этой опции позволит вам прозрачно проводить данные, которые не являются строками или числами. Например, вы можете провести сущность Zend_Xml_Config без предварительной сериализации, с расчетом на то, что вы сможете ее прочитать из кэша.
ignore_user_abort
Если эта опция установлена, ignore_user_abort будет устанавливаться как true во время того как будет записываться кэш. Это помогает предотвратить искажение данных.
Когда все настроено и обозначено, мы объединяем его с Zend_Cache::factory(), что дает нам полностью сконфигурированное кэширование объектов. Теперь мы можем использовать кэширование объектов в нашем коде:
test( $sCacheId ) ) {

// кэша нет, значит, мы должны получить данные сложным путем

$aDataSet = doExpensiveQuery();
$oCache->save( $aDataset, $sCacheId );

} else {

//кэш получен, загружаем из memcache

$aDataSet = $oCache->load( $sCacheId );
}

Логика предельно проста. Во-первых, мы проверяем или выполняется memcache сервер, чтобы определить, существуют ли данные и используются ли они. Если нет, мы загружаем данные как обычно, без кэширования. Если они доступны, мы просто загружаем их из memcache и делаем, что нам нужно.

Отметьте, что если вы не устанавливаете automatic_serialization, как мы сделали выше, вы можете использовать гораздо более простую конструкцию. Когда вы только сохраняете строки, и Zend_Cache не делает вам никаких изменений, данные не проверяются на целостность (насколько я понимаю, они могут быть правильно преобразованы из последовательной формы в параллельную).
load( $sCacheId ) ) ) {

//кэша нет, так что мы должны получить данные сложным путем
$aDataSet = doExpensiveQuery();
$oCache->save( $aDataset, $sCacheId );
}

Обратите внимание, что вы сохраняете несколько строк и все, что вам требуется, это обернуть существующий код в единственный блок if. Только запомните – если это не строка или число, вам нужно будет выполнить serialize/deserialize самостоятельно.

Заключение

Реализация Memcached в Zend Framework удивительно проста. Если у вас есть подходящие ресурсы и достаточно прав для установки Memcached, я не представляю себе причину, по которой вы не захотите этого сделать. Благодаря нескольким дополнительным строкам кода, ваше приложение может мгновенно стать более производительным и легко масштабируемым.