Memcache
Memcache
В данной статье я хочу рассказать о таком замечательном PHP расширении, как Memcache. Подробно о том, что такое кэширование, я рассказывать не буду, скажу лишь в нескольких словах.

Кэширование - это сохранение часто запрашиваемых данных в определенном месте, для дальнейшего ускоренного доступа к ним. Для примера, представим следующую ситуацию - есть активный SQL запрос, который делает выборку данных из какой-нибудь таблицы, в которой этих данных много. С каждым обновлением странице пользователем, этот запрос посылается на обработку MySQL серверу, что создает значительную нагрузку.

Так вот, Memcache - это расширение, позволяющие уменьшить нагрузку, путём кэша данных в оперативной памяти. Как же работать с Memcache? Начнём с того, что Вам потребуется установить данное расширение на Ваш сервер, т.к. оно не поставляется с PHP. Если у Вас свой сервер, то Вы можете зайти в "Расширения PHP", далее выбрать "Установить", найти memcache - установить.

Установка, в среднем, занимает минут 10. После чего сервер будет перезагружен. Если у Вас обычный виртуальный хостинг, то Вам потребуется написать в тех.п оддержку Вашего хостинг-провайдера, и попросить установить Вам это расширение. Но не все хостеры пойдут на это.

Сейчас я расскажу про алгоритм кэширования. В Memcache существует метод (функция), который(ая) проверяет, существует ли переданный в качестве аргумента ключ. Если ключ есть, возвращаются наши данные. Если нет - false. Ну так вот, если ключ есть, выполняется например SQL запрос, возвращающий нам данные. Эти данные, с помощью специального метода (функции), мы заносим в кэш. Этот метод (функция), в качестве аргументов принимает следующие: ключ (по которому потом осуществляется доступ к данным), наши данные (которые могут быть любого типа), флаг (true/false, если true - выполняется сжатие данных), время в секундах (по истечению которого, ключ и данные будут удалены).

Если же метод (функция), который(ая) проверяет существует ли переданный ключ возвращает false, то мы переходим к блоку else, указанному в условии. В этом блоке, мы определённой переменной (к которой мы будем обращаться, чтобы вывести данные), присваиваем то, что вернул метод (функция). То есть - наши данные. Таким образом, SQL запрос будет выполнятся уже не постоянно, а только раз в n секунд. Запрос выполнился, вернул нам данные, мы их закэшировали. Всё. Теперь они будут браться из кэша.

Сейчас я напишу список методов (функций), которые нам понадобятся в работе:
connect() - установить соединение с Memcache сервером.
get() - получить значение по ключу.
set() - установить новый ключ.
delete() - удалить кэш по ключу.
replace() - заменяет один кэш, на другой.
flush() - очистить хранилище. То есть - удалить все закэшированные данные.
add() - добавляет кэш, но с условием, если его не существует.

Есть и другие методы (функции), но о них Вы уже можете почитать в других источниках информации. Я не буду их описывать, ибо они или не понадобятся вообще, или же Вы ими будете пользоваться редко.

Итак, с теорией мы кое как ознакомились. Ну что же, переходим к практике. Я буду писать код, и сразу же объяснять, как он работает.

Открываем соединение:
<?php
$mcache = new memcache; // Экземпляр класса memcache
$mcache->connect('localhost', 1221); // Хост, порт

Готово. Соединение установлено.

Если же у Вас появилась следующая ошибка:
Fatal error: Class 'memcache' not found in ...

Это значит, что PHP расширение Memcache - не установлено.

Запись данных в кэш:
if(!$mcache->get('config'))
{
    $sql    = 'SELECT * FROM `config` WHERE `id` = 1';
    $query  = mysql_query($sql) OR die(mysql_error());
    $config = mysql_fetch_assoc($query);

    $mcache->set('config', $config, false, 600);    
}
else
{
    $config = $mcache->get('config');
}

Сейчас я распишу, что и как делает данный код. Создаем условие, если не существует ключа "config", в переменную sql, занесём наш SQL запрос. В переменную query занесем результат работы функции mysql_query, в которую в качестве аргумента был передан запрос хранящийся в переменной sql. В случае ошибки при выполнении запроса, выводим на экран текст (описание) ошибки.

Далее, в переменную config, попадают все извлечённые из таблицы данные. Теперь $config - это ассоциативный массив, благодаря функции mysql_fetch_assoc(). Следом, мы обращаемся к методу set(), в который передаем аргументы. Как уже ранее писалось - первый аргумент, это название ключа. У нас это config. Второй - это наши данные. Данные могут быть любого типа. В нашем случае - это массив. Третий аргумент - сжатие = false.

Ну и четвёртый аргумент - это время в секундах, по истечению которого, ключ и кэш будут удалены. В нашем случае - это 600 секунд. А значит - 10 минут. С этим разобрались. Идем к блоку else. Он выполнится только в том случае, если переданный ключ существует. В переменной config у нас хранится наш массив с данными. Эти данные будет выводиться не из БД, а из кэша. Да, забыл сказать, что некоторые программисты, в качестве ключа при добавлении нового кэша - используют md5 хэш.

Попробуйте обратиться к массиву config, и вывести какое-нибудь значение. Предположим, что в БД, в момент записи была и есть ячейка sitename. Чтобы получить её значение, воспользуемся оператором вывода echo.

Делается это так:
echo $config['sitename'];

Работает? Отлично. Идем дальше. Случилось так, что нам надо удалить этот ключ, и эти данные. Как поступить? Удалить код, и ждать пока пройдет 10 минут? Нет! Воспользуемся методом delete().

Удаление кэша по ключу:
$mcache->delete('config');

Вот и всё, удалили.

Теперь представим следующую ситуацию. У нас много закэшированных данных, и в БД мы обновили старые данные на новые. Но на сайте то выводятся старые, ведь они выводятся не из БД. Что делать? Опять ждать 10 минут? Удалять по одному ключу и делать перезапись? Нет!

Используем метод flush(), который удалит всё, что закэшировано:
$mcache->flush();

Всё. Теперь все данные были успешно удалены и перезаписаны.

Я описал не все методы которые писал. Почему? Потому что такие методы, как: add(), replace() схоже с set(). Аргументы одинаковы.
Ещё я забыл про один метод, который называется close(). Что он делает? А он у нас закрывает соединение с Memcache сервером. Но вызывать его необязательно, ибо соединение закрывается автоматически.

Закрываем соединение:
$mcache->close();

Да да, вот так вот всё просто.

Итак, сейчас на немного закончим практику. Ибо я ещё хочу кое что рассказать. Стиль, который мы использовали - это ОО (объектно-ориентированный). Memcache также поддерживает и процедурный стиль. Методы (точнее уже функции) называются также. Только подставляется префикс memcache. То есть, уже не $mcache->connect(), а memcache_connect(). Не $mcache->set(), а memcache_set(). Ну думаю ясно. И да, экземпляр класса создавать не надо для процедурного стиля.

Но это ещё не всё. Используя процедурный стиль, каждой функции, первым аргументом придётся передать ссылку на открытое соединение Memcache.

То есть:
$mcache = memcache_connect('localhost', 11211);
memcache_set($mcache, ...);
memcache_get($mcache, ...);
memcache_close($mcache);

Думаю, понятно.

Кэширование, с использованием процедурного стиля:
if(!memcache_get($mcache, 'config'))
{
    $sql    = 'SELECT * FROM `config` WHERE `id` = 1';
    $query  = mysql_query($sql) OR die(mysql_error());
    $config = mysql_fetch_assoc($query);

    memcache_set($mcache, 'config', $config, false, 600);    
}
else
{
    $config = memcache_get($mcache, 'config');
}

В общем всё. Сейчас я хочу подвести итоги.

Запись:
$mcache->set('ключ', 'данные', 'сжатие(true/false)', 'время в секундах');


Чтение по ключу:
$mcache->get('ключ');


Удаление кэша по ключу:
$mcache->delete('ключ')


Удаление всего:
$mcache->flush();


Замена кэша по ключу:
$mcache->replace('ключ', 'новые данные', 'сжатие(true/false)', 'время в секундах');


Запись, при условии что такого ключа нету:
$mcache->add('ключ', 'данные', 'сжатие(true/false)', 'время в секундах');


Закрыть соединение:
$mcache->close();

Настоятельно рекомендую использовать ОО стиль. Ах да, всем известный FaceBook - тоже использует Memcache, насколько мне известно.

Данный вид кэширования, позволяет кэшировать все, что угодно. Можно даже закэшировать всю рекламу на Вашем буксе. Кол-во активных запросов можно свести на ноль. Но стоит понимать, что реально надо кэшировать, а что этого просто не требует. Иначе будет так, что кэширование, обойдется гораздо дороже (имеется в виду нагрузка), чем один активный запрос...

На этом я с Вами прощаюсь. Надеюсь, статья Вам будет полезна. Следующую статью я планирую написать либо о PDO, либо о SQLite, или же кэширование на файлах...


Рубрика: Информация » Программирование   |   Автор: Артём   |   Просмотры: 4479
Комментариев: 3
Публикаций: 0
ICQ: 9468899
- 31 +
  Автор: coolrus   |   Группа: Пользователи   |   Дата: 03 августа 2012  
Спасибо хорошая статья!)
Комментариев: 36
Публикаций: 2
ICQ: 643680
- 6 +
  Автор: Артём   |   Группа: Пользователи   |   Дата: 03 августа 2012  
Че-то маленькая статья получилась. Хотя писал я её не час и не два. wink
Комментариев: 59
Публикаций: 2
ICQ: 207679
- 143 +
  Автор: Scrin   |   Группа: Пользователи   |   Дата: 03 августа 2012  
такая же фигня) пишешь долго получается мало...

С моих статей хоть шоп оживился, продолжаем в том же духе!!
Комментариев: 121
Публикаций: 2
ICQ: 819374
- 118 +
  Автор: Rufus   |   Группа: Программисты   |   Дата: 03 августа 2012  
Статья норм, хоть и не нова.
Комментариев: 75
Публикаций: 5
ICQ: 693161787
- 43 +
  Автор: ByFly   |   Группа: V.I.P.   |   Дата: 04 августа 2012  
Отличная статья!
Комментариев: 12
Публикаций: 0
ICQ: 413479905
- 13 +
  Автор: Pikasso   |   Группа: Пользователи   |   Дата: 07 августа 2012  
порт только 11211
Комментариев: 36
Публикаций: 2
ICQ: 643680
- 6 +
  Автор: Артём   |   Группа: Пользователи   |   Дата: 07 августа 2012  
Pikasso, Угу... Опечатался маленько... fellow
Комментариев: 12
Публикаций: 0
ICQ: 413479905
- 13 +
  Автор: Pikasso   |   Группа: Пользователи   |   Дата: 12 августа 2012  
продолжи статью про вывод массива из мемкеша wink
Информация

Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.