Php memcached примеры. Memcached: установка и настройка. Установка и настройка

Сегодня мы будем разбираться с интересным механизмом кеширования данных: Memcache php . Замечательная сторона memcahe состоит в том, что мы можем кешировать все что угодно, от SQL запросов, до объектов и любых других структур данных.

Что такое Memcache

Memcache – это непросто технология или алгоритм кеширования, в первую очередь это серверная программа, запущенная на веб-сервере. Если вы пользуетесь услугами хостинга, то перед использованием мемкеша в приложении, необходимо убедиться, что memcahe доступен. Сделать это можно с помощью функции phpinfo() .

Концепция

Убедившись в том, что memcahe сервер доступен для использования, давайте познакомимся с концепцией сего механизма кеширования. Самое привлекательное в использовании memcahe php это то, что все закешированные данные хранятся в оперативной памяти сервера. Такой принцип хранения данных, не только экономит процессорное время на формировании их вновь и вновь, но и очень увеличивает скорость доступа к ним.

В упрощенном варианте концепцию работы memcahe можно изложить таким образом: часто используемые php объекты кешируются и сохраняются в ОЗУ сервера в виде набора пар "ключ — объект", при необходимости сохраненные раннее объекты берутся из памяти сервера минуя многочисленные подключения к БД проверки и циклы. В случае когда алгоритм memcahe php не обнаруживает запрашиваемого объекта в памяти, необходимый объект создается обычным образом и сохраняется в кеш.

Как работать с сервером Memcache в PHP

Для работы с серевром Memcache нам потребуется одна из PHP библиотек php-memcache либо php-memcached .

Выбор той или иной библиотеки зависит от индивидуальных потребностей разработчика, в большей своей части, они очень похожи друг на друга, с той разницей, что php-memcached предоставляет несколько большие возможности для работы такие как:

  • CAS токены для версионирования ключей
  • Обратные вызовы (callbacks)
  • Метод getDelayed() позволяющий уменьшить время ожидания, откладывая фактическое чтение ключей
  • Поддержка бинарного протокола
  • Возможность избежать сериализации используя igbinary

Оба модуля php-memcach и php-memcached , не являются стандартными для php, но доступны в репозитории PECL.

В случае работы не на собственном сервере, а на сервере хостинга, выбирать вам не придется, все будет уже настроено.

Пример работы

Сразу обращу ваше внимание на то, что данный пример будет работать на php-memcach и php-memcached одинаково.

Memcach php использует следующие методы для работы с данными:

  1. get — для получения объекта из кэша;
  2. set — запись объекта по ключу в кэш;
  3. add — запись объекта в кэш, если в нем еще нет такого ключа;
  4. replace — запись объекта в кэш, в случае, если ключ уже есть.

Приведу примитивный пример использования кеширования с помощью сервера memcache.

1
2
3
4
5
6
7

$memcache = new Memcache() ;
$memcache -> pconnect ("localhost" , 3211 ) ; //Cоединяемся. По умолчанию можно использовать любой порт
$key = "key_1" ;
$value = array (1 , 2 , 3 , 4 , 5 ) ;
$expire = 600 ;
$memcache -> set ($key , $value , 0 , $expire ) ; // Сохраняем значение на 10 минут
$memcache -> get ("key_1" ) ; // получаем записанный ранее массив

При использовании сервера мемкеша сразу для нескольких проектов, помните, что данные записываются в одну оперативную память. Это значит, что если вы с разных проектов запишите новые значения по одному и тому же ключу, то для обоих будет доступно последнее значение, попавшее в память.

Данная статья носит характер «Скорой помощи». Развернутое описание конкретных действий, которые позволять установить и настроить memcached на сервере.

Начнем с определения.

Memcached - программное обеспечение, реализующее сервис кэширования данных в оперативной памяти на основе хеш-таблицы.

Начальные данные:

  • VPS , работающий на операционной системе Debian ;
  • действующий сайт, к которому можно обратиться по FTP, SSH.

Начнем с последнего пункта. За счет запущенного интернет-ресурса (или его подобия) мы можем просто и быстро выяснить что у нас установлено (быть может, что среди прочего мы найдем и memcached). Создадим файл с названием info.php , в котором напишем:

Выполним код, обратившись в по адресу http://example.com/info.php:

Если среди всего прочего вы отыскали похожую запись — значит все в порядке и дело уже сделано. В противном случае — этот результат мы получим по итогам действий, описанных в данной публикации.

Установка сервера Memcached

Запустим установку командой

Apt-get install memcached php5-memcache

Ожидаем завершения установки. После проверим результаты командой netstat

В результате получаем:

Tcp 0 0 *:11211 *:* LISTEN 13053/memcached

Как мы видим, по умолчанию memcached по-умолчанию «слушает» порт 11211. Следовательно, через данный порт любой желающий сможет подключится и использовать наш memcached-сервер. Обезопасим себя, дадим такое право только своему серверу (localhost). Откроем файл /etc/memcached.conf через панель управления, либо через консоль:

Vi /etc/memcached.conf

Данный файл содержит подробные комментарии. Обязательно ознакомьтесь с ними.

Добавьте строку -l 127.0.0.1 .

Перезагружаем memcached-сервер командой:

/etc/init.d/memcached restart

И проверим еще раз:

Netstat -tap | grep memcached

В результате мы должны получить что-то вроде

Tcp 0 0 localhost.localdo:11211 *:* LISTEN 13092/memcached

Теперь memcached работает только на локальный сервер.

Установка memcache

Перечень команд (версия memcache может отличаться!):

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/memcache.so /usr/lib/php5/20060613/ echo "extension=memcache.so" >> /etc/php5/apache2/php.ini

Перезагружаем Apache:

Apachectl graceful

Проверим скрипт, размещенный нами ранее по адресу http://example.com/info.php . Теперь мы должны найти там пункт Memcache.

Проверим работу Memcached

Создадим файл result.php и запустим его.

connect("localhost", 11211) or exit("Невозможно подключиться к серверу Memcached"); $version = $memcache->getVersion(); echo "Server"s version: ".$version."
\n"; $tmp_object = new stdClass; $tmp_object->str_attr = "test"; $tmp_object->int_attr = 123; $memcache->set("key", $tmp_object, false, 10) or die ("Не получилось оставить запись в Memcached"); echo "Записываем данные в кеш Memcached (данные будут храниться 10 секунд)
\n"; $get_result = $memcache->get("key"); echo "Данные, записанные в Memcached:
\n"; var_dump($get_result); ?>

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

Server"s version: 1.4.13 Записываем данные в кеш Memcached (данные будут храниться 10 секунд) Данные, записанные в Memcached: object(stdClass)#3 (2) { ["str_attr"]=> string(4) "test" ["int_attr"]=> int(123) }

Все так или почти так? Тогда все в порядке. Если нет — попробуйте повторить процедуры.

Статья для новичков . Memcached – это такая штука для кэширования данных в оперативной памяти сервера.

В чем суть. Сайт обычно берет данные из базы, а база - это большой файл на диске, а чтение с диска априори медленнее чем из памяти. Это начинает проявляться не сразу - как только посещаемость переваливает за несколько десятков тысяч человек, а таблицы в базе вырастают до сотен тысяч строк. Более того, сама база данных по определению не эффективна. Допустим, в базе храним 1 000 000 постов, но за последние несколько дней 95% всех просмотров составляют только 100 постов. Но каждый раз нам приходится лезть в огромный файл базы и искать в нем несколько часто запрашиваемых записей - а это увеличивает нагрузку на сервер и время открытия сайта. Если же мы положим эти записи в кэш, то мы ускорим сайт и не нужно покупать мощные сервера. Одним словом, кэш - это профит !

Кэширование бывает разным. Самое простое - кэширование на файлах . Минус в том, что данные по-прежнему хранятся на диске, а это может привести к печальным последствиям . Можно кэшировать промежуточные результаты в базе (например, результаты поиска в некоторых форумных движках хранятся в базе). Ну и самое эффективное это конечно хранение в оперативной памяти. Для этого существует куча сторонних программ: Memcached, eAccelerator, APC, XCache. Кстати, MySQL тоже умеет хранить данные в своем кэше (речь не об индексах в памяти).

Вообще, пишут, что eAccelerator и XCache эффективней чем Memcached, если вы используете один сервер, так как в случае Memcached необходимо открывать TCP-соединение. Но у Memcached есть главное преимущество - это возможность разнесения данных по нескольким серверам. Например, кэш ЖЖ не уместится в памяти ни одного самого мощного сервера. Собственно, Memcached и был придуман для ЖЖ, чтобы можно было хранить данные на нескольких серверах. Но нам, новичкам, пока рано об этом думать.

Особенности Memcached

  • Простая структура хранения данных (ключ-значение).
  • Максимальное время жизни кэша - 30 дней.
  • Максимальный объем одного элемента - 1 Mb
  • Можно хранить объекты, массивы как есть. При кэшировании в файлах или в базе подобные вещи нужно загонять в строку при помощи сериализации перед сохранением.
  • Нет авторизации (пароль-логин). Т.е. если на сервере стоит Memcached, то любой пользователь на этом же сервере может получить к нему доступ.
  • Скорость доступа к данным не зависит от кол-ва элементов в кэше. Да-да, именно так.

Установка

В сети есть куча инструкций по установке, хоть на Unix, хоть на Windows. Кроме самого Memcached нужно еще поставить либу для обращения к Memcached через PHP (по аналогии с базой MySQL - кроме самой базы нужно еще поставить расширение mysql или mysqli).

Но проще всего написать хостеру. На fastvps при заказе сервера Memcached ставят по умолчанию. Главное, указать сколько памяти нужно выделить под кэш. По умолчанию это 67 Mb. У меня 4 Gb оперативы, то можно смело выделить 1 Gb. Вообще, самый простой способ оценить сколько нужно памяти под кэш, это умножить объем базы на 2. Например, базы на всех наших сайтах весят 300 Мб, то под кэш выделяем 600 Мб, а лучше брать 1 Гб, с запасом.

Memcached можно увидеть в phpinfo

Проверка

Обычно Memcached стоит на localhost и доступен через порт 11211
Смотрим статистику

connect("localhost",11211); print_r($memcache->getStats()); ?>

Результат:
Array
=> 5915
=> 583
=> 1309538445
=> 1.2.2
=> 64
=> 0.000000
=> 0.004000
=> 0
=> 0
=> 0
=> 1
=> 2
=> 2
=> 0
=> 0
=> 0
=> 0
=> 0
=> 7
=> 0
=> 1073741824
=> 1
)

Через какое-то время статистика будет выглядеть примерно так

Array
=> 5915
=> 6202245
=> 1315740107
=> 1.2.2
=> 64
=> 3.464216
=> 10.868679
=> 298
=> 17728
=> 120366
=> 1
=> 28654
=> 4
=> 133296
=> 17728
=> 124758
=> 8538
=> 0
=> 11125692
=> 103815319
=> 1073741824
=> 1
)

Оновные параметры:
=> 298 - сколько текущих элементов в кэше.
=> 17728 - сколько всего было элементов в кэше (в том числе и удаленных)
=> 120366 - сколько байт сейчас лежит в кэше
=>1073741824 - сколько байт вообще доступно под кэш (тут 1 Gb)
=> 124758 - сколько раз мы взяли данные из кэша
=> 8538 - сколько раз мы пытались взять данные из кэша, но его там не было или время жизни кэша истекло.

Отношение get_misses/get_hits показывает эффективность использования кэша. Чем оно меньше, тем эффективней используется кэш. В данном случае у нас получается, что 93% данных берется из кэша. Если у вас get_misses/get_hits=1, то значит вы делаете что-то не так (скорее всего ставите слишком малое время жизни кэша).

визуальная статистика
Код выше выводит статистику в сухом виде типа print_r()
Есть красивый вывод статистики - phpMemcachedAdmin

Это обычный php-скрипт. Открываете его у себя на сайте и получаете красивое оформление.
Настраивать ничего не нужно. По умолчанию он коннектится к localhost:11211
Скачать можно на официальной странице .

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

Допустим, у нас есть строка "test111", мы хотим ее закэшировать на 1 день. Придумаем ей какой-нибудь ключ "key1".

connect("localhost",11211); $memcache->set("key1", "test111", false, 86400); // кэшируем на 1 день. $get_result = $memcache->get("key1"); // получаем данные print_r($get_result); ?>

Усложним немного

get($key)) { $get_result = $memcache->get($key); print_r($get_result); } else { $result = "test222"; // $result – результат каких-то вычислений или выборка из БД $memcache->set($key, $result, false, 86400); echo "записали кэш на 1 сутки"; } ?>

Только со второго запуска этого скрипта мы увидим наши данные.

Еще забыл добавить про время жизни кэша. Memcached имеет ограничение на время жизни - 1 месяц. Так вот, если вы поставите 365 дней, то Memcached просто не сохранит их, при этом не выдаст ни какой ошибки. Поэтому, если ваши данные долго не меняются и вы хотите поставить максимальный срок жизни, то указывайте false
$memcache->set($key, $result, false, false);

Особенность именования ключей. Лучше в качестве ключа брать md5(ключ), потому что максимальная длина ключа 250 символов и нельзя использовать пробелы. А когда вы будет кэшировать SQL-запросы с условием, то ключ будет типа $key = "blog_id_1 WHERE activity=1 AND … AND … LIMIT 10"

Более того, в ключ нужно еще добавить какую-то константу, которая определяет, к какому сайт принадлежит кэш.
$key = md5(PROJECT."key2"); // где константа PROJECT="site.com"

Если этого не сделать, то второй сайт на том же сервере может перезаписать данные первого сайта с тем же ключом. Дело в том, что Memcached не имеет авторизации, как например база данных, поэтому приходится вот таким способом ограничивать доступ. Короче говоря, Memcached - это такая большая свалка пар ключ-значение. Поэтому все сайты хранят кэш в одном Memcached. При этом мы не можем, например, взять 10 последних записанных элементов (типа как в базе LIMIT 10). Структура Memcached необычайна проста, но за счет этого мы получаем высокую производительность.

Тегирование

Так как Memcached чрезвычайно прост (данные никак не связаны между собой - есть только связь ключ-значение), то возникают некоторые трудности на практике. Допустим, у нас есть блоги как на Хабре. Мы написали пост, сохранили его в кэш. Создали несколько пар ключ-значение: кэш под сам пост, кэш для блога, в котором отображается этот пост, кэш для прямого эфира, кэш для вывода постов пользователя в профиле этого пользователя и т.д.

$memcache->set("post_id_2211", "данные");
$memcache->set("post_blog_id_11", "данные");
$memcache->set("live_posts", "данные");
$memcache->set("post_user_id_331", "данные");

Но вдруг модератор удалил пост. Нам нужно очистить все кэши, которые связаны с этим постом.

$memcache->delete("post_id_2211");
$memcache->delete("post_blog_id_11");
$memcache->delete("live_posts");
$memcache->delete("post_user_id_331");

Короче, из-за простоты Memcached нам приходится ручками плодить лишний код. Более того, мы должны постоянно помнить какие кэши связаны с другим кэшем. Решение проблемы очень простое. Мы к каждому элементу кэша прикрепляем тег или несколько тегов.
Подробнее можно почитать .

Практика

На практике чистый Memcached никто не использует. Обычно используют какой-то класс-обертку, который поддерживает тегирование. Самым распространенным является решение ZendCache

Скачать одним архивом со всем примерами
Положим класс ZendCache в папку lib

Структура должна быть такой, если смотреть от корня
/lib/DklabCache/...
/class/Cache.class.php
/stat.php
/get_post.php
/update_post.php

Класс-обертка (или как еще называют - врапер (wrapper)) с использованием ZendCache

array(array("host" => MEMCACHED_HOST, "port" => MEMCACHED_PORT, "persistent" => false),), "compression" => false,); self::$instance = new Cache; self::$instance->memcache = new Dklab_Cache_Backend_TagEmuWrapper(new Zend_Cache_Backend_Memcached($aConfigMem)); } else { return NULL; } } return self::$instance; } public function get($key) { return $this->memcache->load($key); } public function set($key, $value, $tags=array(), $timeLife=false) { return $this->memcache->save($value, $key, $tags, $timeLife); } public function delete($key) { $this->memcache->remove($key); } public function clean($cMode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) { return $this->memcache->clean($cMode,$tags); } public function __construct() { } public function __clone() { } } ?>

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

Константа CACHE_USE прописывается отдельно в конфиге. С помощью нее можно включать/выключать кэширование.

Параметр "compression" => false означает, что мы не сжимаем данные в кэше. Сжатие нужно для экономии места в памяти, но сжатие требует некоторого времени. Поэтому, если для вас не критичен объем памяти, то сжатее отключаем.

Параметр "persistent" => false означает выключение постоянного соединения (по аналогии с mysql_pconnect())

Кстати говоря, тут видно как использовать несколько серверов. Если у нас 1 сервер

"servers" => array(array("host" => "localhost", "port" => 11211, "persistent" => false),)

Например у нас 3 сервера Memcached

"servers" => array(array("host" => "11.33.45.11", "port" => 11211, "persistent" => false), array("host" => "11.33.45.12", "port" => 11211, "persistent" => false), array("host" => "11.33.45.13", "port" => 11211, "persistent" => false),)

По-хорошему, подобные вещи нужно вынести из класса в конфиг.

Теперь подключаем этот класс в скрипт, в котором мы хотим что-то кэшировать
Допустим скрипт вывода поста (в архиве это get_post.php)
Примеры конечно не самые лучшие, но лучше так, чем совсем ничего.
Работу с базой я специально отключил, что бы у вас было меньше проблем.

get($key_cache))){ echo "данные взяли из кэша"; return $data; } else { // находим пост в базе (выполняем select) //$data = $DB->selectRow("SELECT * FROM post WHERE id=?d", $postID); // для упрощения примера беем готовый массив (пост привязан к блогу с ID=3) $data = array("id"=>$postID, "blog_id"=>3, "title"=>"Новость 111", "text"=>"какой-то текст"); if (!empty($data)) { if (isset($Cache)) { $Cache->set($key_cache, $data, array("post_update", "post_update_".$postID, "post_blog_".$data["blog_id"]), 3600*24*10); echo "сохранили данные в кэш"; } return $data; } else return null; } } $postID = 25; $post = get_post($postID); print_r($post); ?> Хотим взять пост с id=25. При первом вызове вы должны увидеть надпись "сохранили данные в кэш". При повторных вызовах вы увидите надпись "данные взяли из кэша". Теперь попробуем обновить пост (запускаем скрипт update_post.php) query("UPDATE post SET blog_id =?d, title=?, text=? WHERE id=?d", $blogID, $title, $text, $postID); // чистим теги, связанные с эим постом $Cache = Cache::getInstance(); if (isset($Cache)) { $Cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array("post_update", "post_update_".$postID, "post_blog_".$blogID)); } return true; } $postID = 25; update_post($postID, 3, "test", "test test"); ?>

После чего запускаем скрипт get_post.php и видим, что данных в кэше не было и мы снова сохранили их туда: "сохранили данные в кэш".

На самом деле самое сложное в кэшировании, это простановка правильных тегов . Чтобы при обновлении поста обновилась данные, в которых лежит этот пост.

На примере выше это были теги

  • "post_update_".$postID - сам пост (обычно страница вывода поста)
  • "post_blog_".$blogID - страница блога, где выводится список постов этого блога
  • "post_update" - тег связанный с главной страницей или списком самых лучших постов

Dog-pile эффект

Переводится как «стая собак». Допустим, у вас есть какая-то сложная выборка из базы на 2 секунды. В кэше ее еще нет (или мы сбросили кэш). Приходит первый пользователь, идет запрос в базу, и только спустя 2 секунды эти данные появятся в кэше. Так вот, за эти 2 секунды на сайт могут зайти еще 10 человек, которые инициируют еще 10 таких же сложных запросов в базу (так как данных в кэше еще нет, а первый запрос всё еще выполняется). Отсюда и получается стая собак, которые нагружают сервак.

выглядит это примерно как-то так:)

Решение проблемы описано .
Код выше не предусматривает защиты от dog-pile эффекта. В моем случае нет такой высокой посещаемости и долгих запросов.

Ранее уже была сделана публикация с . Давайте вернемся к данной теме и рассмотрим практику работы с 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 почти всегда используется в паре с БД. Также следовало бы уделить внимание своевременной инвалидации данных в кэше и вопросам безопасности. В общем, тема интересная, и еще далека от закрытия.

Сегодня я представлю вам небольшой фрагмент кода, который научит вас взаимодействовать с 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, но я надеюсь, это был хороший старт для вас.