Использование Memcache при помощи PHP. Использование memcached в php Кэширование директорий в memcache php

Навигаторы 03.04.2024

Любой более или менее развивающийся web проект рано или поздно встречается с задачами, которые лучше всего решать с помощью кэширования. Например, сохранение в какое-либо хранилище агрегированных данных, подсчет и(или) получение которых занимает много времени. Существует несколько вариантов кэширования данных: сохранение данных на диск или в оперативную память. У каждого варианта есть свои плюсы и минусы. Сохранение на диск — медленное, запись происходит последовательно с использование блокировок, количество которых обычно ограниченно оперативной системой. Но данные сохраняются навсегда и будут доступны после перезагрузки сервера. Оперативная память же, напротив, быстрая, без блокировок, но не сохраняется в случае перезагрузки. Хранить в ней не продублированные данные опасно. Если с сохранением на диск все понятно и просто, то работа с памятью более сложна. Существуют приложения, которые берут на себя эту задачу. Одно из которых Memcached. В этой статье мы поговорим о нем.

Memcached — это сервер с открытым кодом, позволяющий кэшировать данные в оперативной памяти. Имеет высокие показатели скорости. Популярен. Обладает большим набором клиентских библиотек, написанных на всевозможных языках программирования.

В Php существует две версии библиотек: php-memcache и php-memcached. Первая старая и больше не развивается. Вторая новая и имеет больший набор функции. Различий в них больше и какую использовать решать вам. В данной статье будет использоваться php-memcached.

Чтобы поближе познакомиться с memcached, создадим небольшое приложение, пользующееся его базовыми возможностями. Мы напишем защиту от подбора пароля при авторизации. Суть приложения будет в том, что при неудачных попытках авторизации, приложение будет сохранять в кэше количество неудачных попыток. Когда это количество превысит установленный минимум, будет блокироваться возможность авторизации на определенное время. Минуты на 2-3. В этом случае мы сильно снижаем эффективность подбора пароля.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 require_once __DIR__. "/func.php" ; if (! extension_loaded ("memcached" ) ) { die ("Memcached extension not installed" ) ; } $USE_CACHE_PROTECTION = true ; $AUTH_MAX_ATTEMPTS = 5 ; $AUTH_LOGIN = "demo" ; $AUTH_PASSWORD = "demo" ; $error = array () ; if (IS_POST() ) { $login = _POST("username" ) ; $password = _POST("password" ) ; if (! $login ) { $error [ "username" ] = "required" ; } if (! $password ) { $error [ "password" ] = "required" ; } // INIT MEMCACHE if ($USE_CACHE_PROTECTION ) { $cache = new Memcached() ; $cache -> addServer ("127.0.0.1" , 11211 ) ; $cacheKey = "prefix::login-protect-" . $login ; } //check cache protection if ($USE_CACHE_PROTECTION && ! $error ) { $attempts = $cache -> get ($cacheKey ) ; // CHECK FAILD ATTEMPTS if ($attempts >= $AUTH_MAX_ATTEMPTS ) { $error [ "global" ] = "max_attempts" ; } } //check auth if (! $error ) { //TODO: use db bro if ($login == $AUTH_LOGIN && $password == $AUTH_PASSWORD ) { // CLEAR DATA ON SUCCESS AUTH if ($USE_CACHE_PROTECTION ) { $cache -> delete ($cacheKey ) ; } stopAndRedirect("success.php" ) ; } if ($USE_CACHE_PROTECTION ) { //INCREMENT ATTEMPTS if (! $cache -> increment ($cacheKey ) ) { $cache -> set ($cacheKey , 1 , 60 ) ; } } $error [ "global" ] = "auth_faild" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

Демо использование memcached в php

Авторизация

Как видно из кода все предельно просто. Создается уникальный ключ, состоящий из префикса сайта, названия задачи и введенного логина. Далее читаем, наращиваем счетчик, удаляем. Стоит обратить внимание на участок кода, где скрипт наращивает счетчик неудачных попыток авторизации. Метод increment возвращает false в случае отсутствия записи в memcached. Поэтому, в случае неудачи мы устанавливаем запись со значением 1 ровно на 60 секунд.

Стоит заострить внимание на том, что мы используем метод increment , а не set(getted_value+1) . Дело в том метод set не дает возможности правильно увеличивать счетчик, так как в между промежутком чтения и записи, данные могут измениться. Например, в это же время другой пользователь будет тоже подбирать пароль. Метод increment же гарантированно увеличит счетчик правильно!

Ранее уже была сделана публикация с . Давайте вернемся к данной теме и рассмотрим практику работы с memcached на примерах.

К сожалению, у меня по прежнему не доходят руки активно заниматься блогом, но наконец-то появился появился первый человек, откликнувшийся на . Его имя Владислав Клименко и именно он является автором данного поста, а я лишь выступаю в роли редактора. Может быть данный пример подтолкнет и других читателей поучаствовать в возвращении Insight IT к жизни.

С уважением,
Иван Блинков

Итак, пара слов о предмете разговора. memcached - это распределенная система кэширования объектов в оперативной памяти. Разрабатывается фирмой (кстати, они являются авторами не только memcached, но и других интересных проектов). Но о них, возможно, в следующий раз. Обычно memcached используется приложениями для временного хранения данных, которые надо часто читать. Приложения не взаимодействуют (обычно) напрямую с сервером memcached, а работают при помощи клиентских библиотек. На настоящее время созданы библиотеки для многих языков программирования (а для некоторых еще и по нескольку альтернативных) - полный список клиентских библиотек доступен на . В целом, данная схема похожа на работу с БД, знакомую многим разработчикам.

Будем рассматривать установку и использование memcached для Linux. Так же при рассмотрении примеров на PHP и обзоре кэширования сессий потребуются PHP и Apache. Возможно, их придется установить, но мы не будем заострять внимание на вопросах установки.

Сервер memcached

Давайте приступим к установке memcached. Практически во всех дистрибутивах Linux memcached можно установить из репозитариев. Если есть желание собрать самую свежую версию, то можно заглянуть на (на момент написания этих строк последняя версия - ). Также, возможно, понадобится установить libevent. Последняя стабильная версия -

Собираем, устанавливаем и запускаем memcached в режиме вывода сообщений. Интересно же посмотреть, что с ним происходит:

Процесс запускается и ждет подключений (по умолчанию на порту 11211). Серверная часть готова обрабатывать подключения клиентов и кэшировать полученные данные.

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

Клиенты memcached

Из всего многообразия клиентских библиотек рассмотрим две:

  • libmemcached (для Си);
  • PECL extension для PHP (построенный на базе предыдущей библиотеки).

Си

Библиотека libmemcached на данный момент активно развивается и представляется наиболее подходящим выбором при работе с Си и PHP. Также, в комплекте с самой клиентской библиотекой поставляются дополнительные утилиты для работы с memcached, позволяющие просматривать, устанавливать, удалять значения в кэше memcached. Кстати, удивляет, что набор утилит идет не с серверной частью, а с клиентской библиотекой.

Итак, приступим к установке libmemcached. На момент написания этих строк текущая версия libmemcached - . Компилируем, устанавливаем. Для начала, наслаждаемся чтением страниц man:

man libmemcached man libmemcached_examples

C библиотекой поставляются описание несложных примеров использования. За более интересными же способами применения имеет смысл заглянуть в исходные тексты утилит, благо все идет вместе.

  • memstat - выдает информацию о сервере memcached
  • memcat - выдает значение по ключу
  • memrm - удаляет значение по ключу
  • memdump - выдает список ключей

Для начала посмотрим, что скажет сервер memcached, запущенный нами немного ранее в режиме выдачи сообщений. Запросим статистику сервера при помощи утилиты memstat:

memstat --servers localhost Listing 1 Server Server: localhost (11211) pid: 14534 uptime: 1950 time : 1247390264 version: 1.4.0 pointer_size: 32 rusage_user: 0.0 rusage_system: 0.0 curr_items: 0 total_items: 0 bytes: 0 curr_connections: 10 total_connections: 11 connection_structures: 11 cmd_get: 0 cmd_set: 0 get_hits: 0 get_misses: 0 evictions: 0 bytes_read: 0 bytes_written: 0 limit_maxbytes: 67108864 threads: 5

Получили статистику - следовательно memcached функционирует и откликается на запросы.

Итак, на настоящий момент готовы к использованию сервер memcached и клиентская библиотека. Осталось дело за малым - внедрить использование memcached в разрабатываемое приложение. Что касается приложения - все в руках разработчиков, а мы рассмотрим небольшой пример работы с базовыми функциями.

memcached предоставляет следующий набор основных функций (их, конечно, больше, но здесь приведены основные):

  • set - занести в кэш пару ключ-значение
  • add - занести в кэш значение при условии, что значения с таким ключом в кэше еще нет
  • replace - обновляет кэш при условии, что значение с таким ключом в кэше уже есть
  • get - получает значение из кэша по указанному ключу

Пример программы на C

#include "stdio.h" #include "string.h" #include "memcached.h" int main ( void ) { char * key = "key" ; char * value = "value" ; uint32_t flags = 0 ; size_t length = 0 ; char * value2 = NULL ; memcached_return rc ; // 1. создать структуру для работы с кэшем memcached_st * memc = memcached_create (NULL ); // 2. указать сервер с которым будем работать memcached_server_add (memc , "localhost" , 11211 ); // 3. занести пару ключ-значение в кэш rc = memcached_set (memc , key , strlen (key ), value , strlen (value ) + 1 , (time_t ) 0 , flags ); if (rc == MEMCACHED_SUCCESS ) { } else { // обработать ошибку } // 4. получить значение value2 = memcached_get (memc , key , strlen (key ), & length , & flags , & rc ); if (rc == MEMCACHED_SUCCESS ) { printf ("%s \n " , value2 ); free (value2 ); } else { // обработать ошибку } // 5. высвободить структуру memcached_free (memc ); return 0 ; }

Программа состоит из 5 основных операций и в особых комментариях не нуждается. Разве что можно отметить, что в пункте 2 можно добавлять много серверов, в случае использования распределенной системы.

Компилируем, возможно придется явно указать пути к библиотекам:

gcc -Wall -o mc mc.c -I/usr/local/include/libmemcached/ -lmemcached

Запускаем:

Видим требуемое значение - должно быть, заработало !

Для уточнения деталей, смотрим сообщения на сервере memcached:

<32 new auto-negotiating client connection 32: Client using the ascii protocol 32 STORED 32 sending key key >32 END <32 quit <32 connection closed.

В данном примере представлены следующие события: подключение клиента, установка пары ключ-значение, чтение данных по ключу и отключение клиента.

Посмотрим статистику на сервере:

memstat --servers localhost Listing 1 Server Server: localhost (11211) pid: 14534 uptime: 4659 time : 1247392973 version: 1.4.0 pointer_size: 32 rusage_user: 0.0 rusage_system: 0.0 curr_items: 1 total_items: 1 bytes: 58 curr_connections: 10 total_connections: 13 connection_structures: 11 cmd_get: 1 cmd_set: 1 get_hits: 1 get_misses: 0 evictions: 0 bytes_read: 58 bytes_written: 58 limit_maxbytes: 67108864 threads: 5

Следующие две строчки показывают, что в кэше появилось значение:

curr_items: 1 total_items: 1

Посмотрим на данное значение:

memcat --servers localhost key value

Итак, приложение, использующее memcached - готово.

PHP

Для начала установим PECL extension для PHP - memcached

pecl install memcached

На этом этапе возможно появление сообщения об ошибке вида:

ERROR: "phpize" failed

Это означает, что не установлен пакет php-dev или его аналог. Устанавливаем его и можно пробовать снова:

pecl install memcached install ok: channel://pecl.php.net/memcached-1.0.0 You should add "extension=memcached.so" to php.ini

Как нам и советуют, дописываем extension=memcached.so в php.ini и перезапускаем Apache.

Смотрим информацию об используемом PHP:

memcached support enabled Version 1.0.0 libmemcached version 0.31 Session support yes igbinary support no

Пример программы на PHP

Можно смело использовать обращения к memcached из PHP. Как обычно, рассмотрим пример:

addServer ("localhost" , 11211 ); $m -> set ("phpkey" , "phpvalue" ); var_dump ( $m -> get ("phpkey" )); ?>

Результат работы данного скрипта:

string(8) "phpvalue"

Итак, PHP-приложение, использующее memcached - готово.

Кэширование данных сессий

Memcached можно использовать и как хранилище данных сессий для PHP. Такой подход часто используется в реальных приложениях. Давайте рассмотрим, что для этого надо сделать.

Вносим изменения в php.ini

;session.save_handler = files session.save_handler = memcached ;session.save_path = /var/lib/php5 session.save_path = localhost:11211

Параметр session.save_handler указывает, что теперь данные будут храниться в memcached. Второй параметр - session.save_path указывает сервер memcached (их может быть указано несколько, через запятую) на котором будут сохранятся данные.

Перезапускаем Apache - и готово!

Теперь надо проверить, что теперь данные сессии реально хранятся не на диске, а в memcached.

Рассмотрим работу несложного скрипта, заносящего что-нибудь в сессию:

Запускаем скрипт, он заносит данные в сессию, после чего смотрим на кэш

memdump --servers localhost key keyphp memc.sess.key.3ff8ccab14424082ff83a6dfbcf0941f

Итак - к нашим знакомым по предыдущим примерам ключам, добавился ключ с характерным именем memc.sess.key..

Хранение данных сессии перенесено в систему кэширования. Более подробную информацию по работе с memcached из PHP можно почитать .

Заключение

Мы рассмотрели установку и примеры использования memcached. Следует особо подчеркнуть, что memcached - это не система хранения данных, поэтому на практике memcached почти всегда используется в паре с БД. Также следовало бы уделить внимание своевременной инвалидации данных в кэше и вопросам безопасности. В общем, тема интересная, и еще далека от закрытия.

В интернете достаточно много информации на данную тему, но, несмотря на это, многие обходят её стороной. Цель данного поста, разъяснить на пальцах основы взаимодействия с Memcached.

Что такое Memcache и какое отношение он имеет к PHP?

Memcache разработан для кэширования данных, генерация которых требует большого количества ресурсов. Такого рода данные могут содержать что угодно, начиная с результатов запроса к базе данных и заканчивая тяжеловесным куском шаблона. Memcached не входит в базовый набор модулей, поставляемых с PHP, однако он доступен в репозитории pecl.

Установка и настройка

В качестве рассматриваемого дистрибутива я решил использовать Debian, потому как он наиболее часто используется при создании web-серверов. Модуль Memcached для PHP доступен в репозитории уже скомпилированным (php5-memcached), но я опишу процесс установки из исходного кода, так как не все репозитории настолько богаты, как дебиановский.

Устанавливаем сервер Memcached

#apt-get install memcached
Для начала, Вам хватит следующего конфига:
#/etc/memcached.conf
#Memcached будет работать, как демон
-d
#Лог будет складывать туда
logfile / var/ log/
#Отведём 256 мегабайт ОЗУ под хранилище
-m 256
#Слушать будет этот порт
-p 11211
#В последствии желательно поменять
-u nobody
#Слушаем localhost
-l 127.0.0.1

#/etc/init.d/memcached restart
Проверяем
# netstat -tap | grep memcached
tcp 0 0 localhost:11211 * :* LISTEN 13036 /

Компилируем и устанавливаем модуль для PHP

apt-get install php5-dev libmemcache-dev

Pecl download memcache
tar xzvf memcache-2.2.6.tgz
cd memcache-2.2.6/
phpize && ./ configure --enable-memcache && make
cp modules/ / usr/ lib/ php5/ 20060613 /

echo "extension=memcache.so" >> / etc/ php5/ apache2/ php.ini
/ etc/ init.d/ apache2 restart


Вот и всё! Совсем не сложно.

Примеры использования

1. Базовые операции

  1. //Создаём новый объект. Также можно писать и в процедурном стиле
  2. = new ;
  3. -> connect ("127.0.0.1" , 11211 ) or die («Could not connect» ) ;
  4. //Попытаемся получить объект с ключом our_var
  5. $var_key = @ -> get ("our_var" ) ;
  6. if (! empty ($var_key ) )
  7. //Если объект закэширован, выводим его значение
  8. echo $var_key ;
  9. else
  10. //Если в кэше нет объекта с ключом our_var, создадим его
  11. //Объект our_var будет храниться 5 секунд и не будет сжат
  12. -> set ("our_var" , date ("G:i:s" ) , false , 5 ) ;
  13. //Выведем закэшированные данные
  14. echo -> get ("our_var" ) ;
  15. -> close () ;

В результате выполнения этого кода каждый раз будет выводиться время с точностью до секунд. Однако обновляться оно будет раз в 5 секунд, пока не очистится кэш. В данном примере проиллюстрированы самые простые операции, но в производительности мы скорее потеряем, чем выиграем. Ведь нам каждый раз придётся подключаться к серверу…

2. Повышаем производительность

2.1 С кэшированием
  1. < ? php
  2. function LoadCPU()
  3. //Функция, которая должна зугрузить процессор
  4. $image = imagecreate(800 , 600 ) ;
  5. //Белый фоновый цвет
  6. $color = imagecolorallocate($image, 255 , 255 , 255 ) ;
  7. //Чёрный
  8. $color2 = imagecolorallocate($image, 0 , 0 , 0 ) ;
  9. for ($i = 0 ; $i < 10000 ; $i++ ) {
  10. imagesetpixel($image, rand (0 , 800 ) , rand (0 ,600 ) , $color2) ;
  11. //Выбрасываем указатель
  12. return $image;
  13. //Создаём новый объект Memcache
  14. = new ;
  15. //Соединяемся с нашим сервером
  16. - > connect("127.0.0.1" , 11211 ) or die("Could not connect" ) ;
  17. //Попытаемся получить объект с ключом image
  18. $image_bin = - > get("image" ) ;
  19. if (empty($image_bin) ) {
  20. //Если в кэше нет картинки, сгенерируем её и закэшируем
  21. imagepng(LoadCPU() ,getcwd() ."/tmp.png" ,9 ) ;
  22. $image_bin = file_get_contents(getcwd() ."/tmp.png" ) ;
  23. unlink(getcwd() ."/tmp.png" ) ;
  24. - > set("image" , $image_bin, false , 30 ) ;
  25. //Выведем картинку из кэша
  26. header("Content-type: image/png" ) ;
  27. echo $image_bin;
  28. //Закрываем соединение с сервером Memcached
  29. - > close() ;
  30. ? >

В данном примере приведена функция, которая создаёт изображение размером 800x600 и расставляет на нём 10 000 точек. Один раз, сгенерировав такое изображение, в дальнейшем мы лишь выводим его на экран, не генерируя заново.
2.2 Без кэширования
  1. function LoadCPU()
  2. //Функция, которая должна загрузить процессор
  3. //Создадим изображение 800x600
  4. $image = imagecreate (800 , 600 ) ;
  5. //Белый фоновый цвет
  6. $color = imagecolorallocate ($image , 255 , 255 , 255 ) ;
  7. //Чёрный
  8. $color2 = imagecolorallocate ($image , 0 , 0 , 0 ) ;
  9. for ($i = 0 ; $i < 10000 ; $i ++ ) {
  10. //Расставим 10 000 точек в случайном порядке
  11. imagesetpixel ($image , rand (0 , 800 ) , rand (0 , 600 ) , $color2 ) ;
  12. //Выбрасываем указатель
  13. return $image ;
  14. //Выводим изображение, не кэшируя
  15. header ("Content-type: image/png" ) ;
  16. imagepng (LoadCPU() , "" , 9 ) ;

Тут всё гораздо проще и привычней: генерируем изображение каждый раз заново.
Результаты
Я протестировал оба скрипта на производительность. Одна и та же машина в первом случае выдала 460 ответов в секунду, а во втором лишь 10. Чего и следовало ожидать.

Ещё несколько полезных функций

addServer - в случае, если у вас в распоряжении несколько кэширующих серверов, вы можете создать некий кластер, добавляя сервера в пул. Следует обратить внимание на параметр weight . Он указывает на то, сколько памяти вам будет доступно на конкретном сервере.
delete - из названия понятно, что данный метод удаляет из кэша объект с заданным ключом.
replace - заменяет значение объекта с заданным ключом. Используйте в случае, если Вам понадобится изменить содержимое объекта, раньше чем истечёт время его жизни.

Итог

С моей точки зрения, применять кэширование стоит только на высоконагруженных ресурсах. Ведь каждый раз, подключаясь к серверу Memcached, вы тратите драгоценное время, что скорее всего не будет оправданным. Что касается больших проектов, лучше сразу написать больше строк кода, чем потом делать это в попыхах, с мыслью о том, что ваш сервис лежит. Также не стоит забывать о расходовании памяти! Учтите, что положив 300 мегабайт в кэш, вы отняли у себя 300 мегабайт ОЗУ...
В завершение хочу сказать, что данная статья не раскрывает все прелести технологии, однако я надеюсь, что она стимулирует Вас к самосовершенствованию. Спасибо за прочтение, многоуважаемый %username%!

UPD: Ещё один интересный момент. Memcached, есть PHP API к libmemcached. А Memcache, библиотека для php, не использующая libmemcached.

Модуль Memcache предоставляет удобные процедурный и объектно-ориентированный интерфейсы к механизму кэширования memcached. Memcache это очень эффективный демон кэширования, который был специально разработан для уменьшения нагрузки на базу данных для высоконагруженных, динамичных веб-приложений.

Memcache модуль также предоставляет обработчик сессии. Более подробную информацию о Memcached можно найти на сайте memcached.org

В принципе описания установки и настройки на русском языке уже готово и с ним можно ознакомится .

Имейте ввиду сохранять в кэше можно любые типы данных: и переменные, и объекты, и массивы, НО НЕ РЕСУРСЫ!

Если какой либо объект имеет в своём составе свойство - ресурс, например соединение с базой данных, или содержит другой объект имеющий подобные свойства, то эту ситуацию нужно обрабатывать отдельно, например переопределив метод __sleep() в котором этот ресурс нужно "убить" и метод __wakeup() в котором этот ресурс нужно возродить.

На самом деле все эти методы можно подразделить на 3 группы:

  1. Работа со значениями
  2. Работа с серверами и соединениями
  3. Получение информации

Работа со значениями

Методы этой группы позволяют делать следующее:

  • Устанавливать значения
  • Удалять эти значения
  • Заменять эти значения
  • Обращаться к этим значения по ключу
  • Управлять сроком жизни значений

Пара специфичных методов для инкремента и декремента целочисленных значений.

Memcache::set()
Memcache::add()

Позволяют установить значение, задать сжатие и время жизни для этого значения. Единственное различие в поведении этих методов это то, что метод Memcache::add - вернёт FALSE, если значение с таким ключём уже установлена.

bool Memcache::add
bool Memcache::set (string $key , mixed $var [, int $flag [, int $expire ]])

  • string $key - ключ значения, используя его мы оперируем значением.
  • mixed $var - значение.
  • константы
connect("localhost", 11211, 30); $cache->add("myfirst", 1000, MEMCACHE_COMPRESSED, 15); $cache->set("mysecond", 2000, MEMCACHE_COMPRESSED, 15);

Memcache::get()

Вернёт запрошенное значение или FALSE в случае неудачи, или, если значение с таким ключём ещё не установлено.

Можно передать массив ключей значений, тогда Memcache::get тоже вернёт массив, он будет содержать найденные пары ключ-значение.

Предупреждения!

Если в имени ключа присутствует обратный слэш, то результаты работы будут непредсказуемы!

Есть у Memcached и некоторые болячки: по некоторым данным, он (иногда) подвержен ошибкам переполнения буфера , который время от времени приводит к перезаписи [частичной] данных и, следовательно, делает невозможным десериализацию структур, не забудьте проверить, если в результате получения массива или объекта Memcache::get вернёт bool, dobule или long, значит что то пошло не так.

string Memcache::get (string $key [, int &$flags ])
array Memcache::get (array $keys [, array &$flags ])

  • string $key - ключ значения, или массив ключей, значения которых нужно получить.
  • int $flag - назначение этого параметра осталось для меня тайной. Я пробовал использовать некоторые целочисленные значения, но это не дало ни какого эффекта. Да и примеры в основном даны без его использования, из чего мною сделан вывод: можно прекрасно работать и без него:)
connect("localhost", 11211, 30); $cache->add("myfirst", 1000, MEMCACHE_COMPRESSED, 15); $cache->set("mysecond", 2000, MEMCACHE_COMPRESSED, 15); print_r($cache->get(array("myfirst","mysecond")));

Результат:

Array ( => 1000 => 2000)

Memcache::delete()

Удалить значение из кэша.

Замечание:

Этот метод работает не всегда (Зависит от версии программного обеспечения)! в конце страницы указаны случаи когда Memcache::delete работает, а когда нет.

Что ж, из стабильных вариантов остаётся только обнулять ненужные значения:

$cache->set("three", NULL);

Один только минус - ключ в этом случае ни куда не девается

string Memcache::delete (string $key [, int $timeout = 0 ])

  • string $key - ключ значение, которого нужно удалить.
  • int $timeout - Этот параметр так же устарел и не поддерживается, по умолчанию равен 0 секунд. Не используйте этот параметр.

Memcache::replace()

Перезаписать существующее значение.

Memcache::replace() должна использоваться, чтобы заменить существующее значение . В случае, если значение с таким ключом не существует, Memcache::replace() возвращает FALSE. В остальном Memcache::replace() ведет себя так же, как и Memcache::set(). Также можно использовать функцию memcache_replace()

string Memcache::replace (string $key , mixed $var [, int $flag [, int $expire ]])

  • string $key - ключ, значение которого нужно заменить.
  • mixed $var - новое значение.
  • int $flag - Флаг, указвающий, использовать ли сжатие (Здесь то и нужна Zlib) для сохраняемого значения, можно использовать константы
  • int $expire - Время жизни значения(кэша). Если равно нулю, то бессрочно. Вы также можете использовать метку времени или количество секунд, начиная с текущего времени, но тогда число секунд, не может превышать 2592000 (30 дней).
connect("localhost", 11211, 30); $cache->add("one", 111, 0, 15); $cache->add("two", 222, 0, 15); $cache->add("three", 333, 0, 15); $cache->replace("three", 777); print_r($cache->get(array("one","two","three"))); Array ( => 111 => 222 => 777)

Memcache::increment()

Увеличивает значение указанного ключа на указанное значение. Если значение указанного ключа не числовое и не может быть конвертировано в число, то оно изменит свое значение на значение, указанное как второй параметр. Memcache::increment() не создает элемент, если он еще не существует.

Не советуют использовать Memcache::increment() cо значениями, которые были сжаты (установлены с флагом MEMCACHE_COMPRESSED), потому, что потом будут "сюрпризы", когда вы попытаетесь получить эти значения при помощи Memcache::get()

Лично я проверил и ни каких глюков не заметил:)

int Memcache::increment

  • string $key - ключ, значение которого нужно инкрементировать.
  • int $value - значение инкремента.
connect("localhost", 11211, 30); $cache->set("someOne", 10, 0, 5); $cache->increment("someOne", 10, 0, 5); $cache->increment("someOne", 10, 0, 5); echo $cache->get("someOne");// выведет 30

Memcache::decrement()

Уменьшает значение указанного ключа на указанное значение. Аналогично Memcache::increment(), текущее значение элемента преобразуется в числовое и после этого уменьшается

int Memcache::decrement (string $key [, int $value = 1 ])

  • string $key - ключ, значение которого нужно декрементировать.
  • int $value - значение декремента.

Memcache::flush()

Memcache::flush() делает недействительными все существующие значения. Memcache::flush() на самом деле не освобождает ресурсы памяти, а только помечает все элементы как устаревшие, и занимаемая память будет доступна для использоавания новыми значениями. Также вы можете использовать функцию memcache_flush()

bool Memcache::flush (void)

Пример ниже не выведет ничего.

connect("localhost", 11211, 30); $cache->set("someOne", 111, 0, 5); $cache->set("someTwo", 222, 0, 5); $cache->set("someTree", 333, 0, 5); $cache->flush(); //Очистит кэш print_r($cache->get(array("someOne","someTwo","someTree")));

Работа с серверами и соединениями.

Memcache может работать, как с одним сервером, так и пулом (набором) серверов.

Если вы будете использовать только один сервер для обслуживания кэша, то для инициализации работы Вам будет достаточно создать объект кэша, и использовать метод Memcache::connect

Если вы собираетесь формировать пул серверов, то тут потребуется сначала создать объект кэша, а потом методом Memcache::addServer добавить в него требуемое количество серверов.

Memcache::connect()

Устанавливает соединение с сервером Memcached. Соединение, которое было открыто с помощью Memcache::connect() будет автоматически закрыто по завершению скрипта, но Вы можете закрыть его явно используя Memcache::close(). Также вы можете использовать функцию memcache_connect ().Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

bool Memcache::connect

connect("localhost", 11211, 30);

Memcache::pconnect()

Этот метод похож на Memcache::connect() с той лишь разницей, что он устанавливает постоянное соединение. Это соединение не закрывается по окончанию выполнения скрипта и вызовом Memcache::close(). Также вы можете использовать функцию memcache_pconnect().Возвращает Memcache object в случае успешного завершения или FALSE в случае возникновения ошибки.

mixed Memcache::pconnect (string $host [, int $port [, int $timeout ]])

  • Этот параметр может также указать другие транспорты, как unix:///path/to/memcached.sock т.е. использовать UNIX сокеты, в этом случае порт должен быть установлен в 0.
  • Установите этот параметр в 0, если предполагается использование сокетов.
  • int $timeout - Лимит в секундах, для подключения к демону. Подумайте дважды, прежде чем изменять значение по умолчанию 1 секунда - вы можете потерять все преимущества кэширования, если ваше соединение будет происходить слишком долго.
pconnect("localhost", 11211, 30);

Memcache::close()

Закрывает соединение с сервером Memcached. Эта функция не закрывает постоянные соединения, которые закрываются только во время выключения/перезагрузки веб-сервера. Также можно использовать функцию memcache_close().

bool Memcache::close (void)

Memcache::addServer()

Добавляет сервер в пул соединений. Соединение, которое было открыто с помощью Memcache::addServer() будет автоматически закрыто по завершению скрипта, так же вы можете закрыть его вручную с Memcache::close(). Можно использовать функцию memcache_add_server()

При использовании Memcache::addServer (в отличие от Memcache::connect() и Memcache::PConnect()) сетевое соединение не установается, пока оно на самом деле не потребуется. Таким образом, нет накладных расходов при добавлении большого количества серверов в пул, даже если они и не потребуются вовсе.

Пул серверов обеспечивает более высокую отказоустойчивость. Любые ошибки сокетов, или ошибки Memcached на уровне сервера (кроме ошибок памяти) вызвают перераспределение ресурсов. Такие ошибки клиента, как добавление существующего ключа не вызовет сбоев.

Замечание:

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

bool Memcache::addServer (string $host [, int $port = 11211 [, bool $persistent [, int $weight [, int $timeout [, int $retry_interval [, bool $status [, callable $failure_callback [, int $timeoutms ]]]]]]]])

  • string $host - Хост Memcached. Этот параметр может также указать другие транспорты, как unix:///path/to/memcached.sock т.е. использовать UNIX сокеты, в этом случае порт должен быть установлен в 0.
  • int $port - порт, на котором Memcached слушает соединения. Установите этот параметр в 0, если предполагается использование сокетов.
  • bool $persistent - Устанавливает использование постоянного соединения. По умолчанию в значение TRUE.
  • int $weight - Чем больше, тем вероятнее, что данный сервер будет выбран для хранения значений. Т.е. это своеобразный "вес" сервера в общем пуле, косвенно это ещё и предполагаемая нагрузка на сервер.
  • int $timeout - Лимит в секундах, для подключения к демону. Подумайте дважды, прежде чем изменять значение по умолчанию 1 секунда - вы можете потерять все преимущества кэширования, если ваше соединение будет происходить слишком долго.
  • string $timeoutms - не описана.

Получение информации

Memcache::getExtendedStats()

Возвращает двумерный, ассоциативный массив статистики серверов. Массив ключей типа "хост:порт" сервера. Значения содержат отдельные параметры статистики. Отказавшие сервера будет иметь значение FALSE. Вы также можете использовать функцию memcache_get_extended_stats()

Замечание:

Эта функция была добавлена в Memcache в версии 2.0.0

array Memcache::getExtendedStats ([ string $type [, int $slabid [, int $limit = 100 ]]])

А теперь прикол:

Тип статистики "cachedump" был удален из Memcached по соображениям безопасности

Пример вывода информации (вызов без параметров) :

Array ( => Array ( => 5179 => 966862 => 1336505233 => 1.4.5 => 64 => 160.302880 => 483.975109 => 6 => 358080 => 13 => 15037476 => 3501979 => 46 => 11507898 => 3529578 => 0 => 0 => 0 => 76 => 0 => 0 => 0 => 0 => 0 => 0 => 0 => 1643906080 => 11298732744 => 67108864 => 1 => 0 => 4 => 0 => 3295454 => 7623 => 3501915 => 0 => 1825755) ...)

Memcache::getServerStatus()

Возвращает статус сервера "онлайн/оффлайн". Можно также использовать функцию memcache_get_server_status()

Замечание:

Эта функция была добавлена в Memcache в версии 2.0.0

int Memcache::getServerStatus (string $host [, int $port = 11211 ])

  • string $host - Хост Memcached.
  • int $port - порт, на котором Memcached слушает соединения.

Memcache::getStats()

Возвращает ассоциативный массив со статистикой сервера. Массив ключей соответствуют статистике параметры и значения для значения параметра. Также можно использовать функцию memcache_get_stats()

array Memcache::getStats s ([ string $type [, int $slabid [, int $limit = 100 ]]])

  • string $type - Тип статистики. Допустимые значения: {reset, malloc, maps, cachedump, slabs, items, sizes}. Согласно спецификации протокола Memcached эти дополнительные аргументы "могут быть изменены для удобства разработчиков".
  • int $slabid - Используется, когда первый параметр установлен в "cachedump" определяет сервер, который будет использоваться для отладки.
  • int $limit - Используется, когда первый параметр установлен в "cachedump" ограничивает количество записей в дамп.

Memcache::getVersion()

Возвращает строку - номер версии сервера. Также вы можете использовать функцию memcache_get_version() .

string Memcache::getVersion (void)

Memcache::setCompressThreshold()

Обеспечивает автоматическое сжатие больших значений. Вы также можете использовать функцию memcache_set_compress_threshold()

Замечание:

Эта функция была добавлена в Memcache в версии 2.0.0

bool Memcache::setCompressThreshold (int $threshold [, float $min_savings ])

  • int $threshold - Минимальная длина значения, которое требуется сжимать автоматически.
  • float $min_savings - Задает коэфициент сжатия. Указанное значение должно быть между 0 и 1. Значение по умолчанию составляет 0,2 дает минимум 20% экономии сжатия.

Memcache::setServerParams()

Изменяет параметры сервера прямо во время выполнения. Вы также можете использовать функцию memcache_set_server_params() .

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Замечание:

Эта функция была добавлена в Memcache в версии 2.0.0

bool Memcache::setServerParams (string $host [, int $port = 11211 [, int $timeout [, int $retry_interval = false [, bool $status [, callable $failure_callback ]]]]])

  • string $host - Хост Memcached.
  • int $port - порт, на котором Memcached слушает соединения.
  • int $timeout - Лимит в секундах, для подключения к демону. Подумайте дважды, прежде чем изменять значение по умолчанию 1 секунда - вы можете потерять все преимущества кэширования, если ваше соединение будет происходить слишком долго.
  • int $retry_interval - Устанавливает, как часто отказавший сервер будет опрашиваться, значение по умолчанию составляет 15 секунд. Установка этого параметра в -1 отключает автоматический повтор запросов.
  • bool $status - Помечает сервер как ONLINE. Установка этого параметра в FALSE и retry_interval -1 позволяет отказавшему серверу хранится в пуле активных серверов, чтобы не влиять на ключевые алгоритмы распределения. Обращения к этому серверу будут распределятся между оставшимися доступными серверами. По умолчанию значение TRUE, то есть сервер должен рассматриваться как ONLINE.
  • callable $failure_callback - Позволяет пользователю указать функцию обратного вызова для запуска при обнаружении ошибки. Функция должна принимать два параметра, имя хоста и порт вышедшего из строя сервера.

Сегодня я представлю вам небольшой фрагмент кода, который научит вас взаимодействовать с Memcache. Для того чтобы установить Mediatemple на хостинге вам необходимы данные для SSH.

Кто использует Memcache?

Memcache была разработана Danga Interactive для того, чтобы увеличить скорость работы портала LiveJournal.com. Memcache сводит время загрузки из базы данных практически до нуля, от чего растёт скорость загрузки страницы для пользователей, ускоренное управление ресурсами и т.д. На данный момент FaceBook является самым крупным пользователем сервиса Memcache. Учитывая количество людей прибывающих на FaceBook ежедневно, он чуть не завалил данный сервис - и для них выделили отдельное место.

Что такое Memcache?

Ну что, интересно стало? Memcache является универсальной системой распределения кэшированных элементов. Если в кэше ничего нет, то делается запрос к базе и результаты записываются в Memcache:

Memcache предоставляет 5 функций:

  • get() - извлекает значение по ключу
  • set() - устанавливает значение
  • add() - добавляет кэш, если его не существует
  • replace() - заменяет кэш
  • flush() - удаляет все закэшированные данные

Код

Если вы установили у себя Memcache, то вы можете начать им пользоваться. Существует мнение, что много кэша это плохо. Я с этим абсолютно не согласен! Чем быстрее грузится ваш сайт - тем лучше!

  • Первые две строки производят подключение к Memcache.
  • Далее следует скрипт подключения к базе данных.
  • Потом создаём ключ. Когда мы хотим поместить данные в Memcache, то нам необходимо передать 3 элемента для вставки: ключ, значение и время жизни кэша. Ключ необходим для получения доступа к данным. В этом примере вы можете увидеть, что я использую в качестве ключа MD5 хэш запроса.
  • Дальше мы проверяем существует ли кэш. Проверка вернёт нам true или false. Если он есть, получаем к нему доступ.
  • Если кэша нет, то мы подключаемся к базе и достаём значения. Для создания кэша используем следующее выражение: $memcache->set($key, $row, TRUE, 20); $row хранит массив того, что мы достали из базы. 20 это время жизни в кэша в секундах.

$memcache = new Memcache; $memcache->connect("127.0.0.1", 11211) or die ("Could not connect"); include("includes/connect.php"); //создать ключ, затем проверить кэш $key = md5("SELECT * FROM memcached_test where name="ashley""); $get_result = $memcache>get($key); if ($get_result) { echo $get_result["name"]; echo $get_result["username"]; echo "Data Pulled From Cache"; } else { // Получить данные из базы и создать кэш $query="SELECT * FROM memcached_test where name="ashley";"; $result = mysql_query($query); $row = mysql_fetch_array($result); print_r($row); $memcache>set($key, $row, TRUE, 20); // Хранить результат 20 секунд echo "Data Pulled from the Database"; }

Это самый простой пример использования memcache, но я надеюсь, это был хороший старт для вас.

Рекомендуем почитать

Наверх