Установка memcached в Ubuntu 14.04

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

Один из способов решения этой проблемы – использование системы кэширования объектов памяти, например memcached. Memcached – это система кэширования, работающая путем временного хранения в памяти информации, которая обычно извлекается из базы данных. Следующий запрос этой информации обрабатывается очень быстро из памяти, что позволяет снизить нагрузку на базу данных.

Данный мануал поможет установить memcached на сервер Ubuntu 14.04 и разобраться с тем, как работает эта система.

Требования

  • Сервер Ubuntu 14.04.
  • Пользователь с доступом к sudo.

Все необходимые инструкции можно найти в руководстве по начальной настройке сервера.

1: Установка memcached и зависимостей

Для начала нужно загрузить все компоненты их репозитория Ubuntu.

Обновите индекс пакетов:

sudo apt-get update

Теперь нужно установить memcached, а также базу данных MySQL и PHP, а также расширение PHP, которое обрабатывает взаимодействия memcached. Для этого введите команду:

sudo apt-get install mysql-server php5-mysql php5 php5-memcached memcached

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

Во время установки MySQL будет предложено выбрать и подтвердить пароль администратора.

Читайте также: Установка MySQL в Ubuntu 14.04

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

Система кэширования memcached установлена и готова к работе. Теперь можно подтвердить, что установка прошла успешно. Есть несколько способов сделать это.

Первый способ довольно прост: нужно запросить у PHP информацию о расширении memcached и убедиться, что оно включено. Для этого нужно создать страницу справки PHP.

Создайте в корневом каталоге веб-сервера файл info.php. Для Apache в Ubuntu 14.04 это /var/www/html.

sudo nano /var/www/html/info.php

Добавьте в файл следующие строки:

<?php
phpinfo();
?>

Это код просто вызывает функцию PHP, которая собирает информацию о сервере в макет и отображает ее в браузере.

Теперь можно запросить эту страницу в браузере. Для этого введите в адресную строку:

http://server_domain_name_or_IP/info.php

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

Это значит, что расширение memcached включено и веб-сервер видит его.

Также работу memcached можно проверить с помощью команды:

ps aux | grep memcached
memcache  6584  0.0  0.0 327448  3004 ?        Sl   14:07   0:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1
demouser  6636  0.0  0.0  11744   904 pts/0    S+   14:29   0:00 grep --color=auto memcached

Запросить данные о сервисе можно с помощью команды:

echo "stats settings" | nc localhost 11211

Чтобы перезапустить сервис, используйте команду:

sudo service memcached restart

3: Проверка работы memcached

Теперь нужно убедиться, что memcached может кэшировать и хранить данные.

Для этого создайте другой сценарий PHP. Он будет немного сложнее.

В корневом каталоге откройте файл cache_test.php:

sudo nano /var/www/html/cache_test.php

Внутри откройте тег:

<?php
?>

Внутри этого тега нужно создать экземпляр PHP-объекта memcached и поместить его в переменную. Также нужно определить порт, где этот объект PHP может подключаться к сервису memcached, запущенному на сервере. По умолчанию memcached использует порт 11211:

<?php
$mem = new Memcached();

$mem->addServer("127.0.0.1", 11211);

?>

Затем нужно настроить memcached для запроса ключей из кэша. Вы можете выбрать любой ключ, поскольку пока что он еще не был создан (к примеру, можно использовать blah). Результат этого запроса будет сохранен в переменную $result:

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
$result = $mem->get("blah");
?>

Затем нужно убедиться, что memcached возвращает какой-то результат. Если memcached находит ключ blah, нужно вывести значение, связанное с этим ключом. Если memcached не удалось найти соответствующий ключ, нужно вывести сообщение об этом.

Затем нужно присвоить ключу значение, чтобы система memcached вывела его на экран.

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
$result = $mem->get("blah");
if ($result) {

echo $result;


} else {


echo "No matching key found.  I'll add that now!";


$mem->set("blah", "I am data!  I am held in memcached!") or die("Couldn't save anything to memcached...");


}

?>

Сценарий готов. Теперь откройте в браузере ссылку:

http://server_domain_name_or_IP/cache_test.php

Сначала вы должны увидеть такое сообщение:

No matching key found. I’ll add that now!

Если вы обновите страницу, вы увидите другое сообщение:

I am data! I am held in memcached!

Как видите, теперь memcached кэширует данные.

4: Кэширование базы данных

Убедившись, что memcached может кэшировать данные, вы можете попробовать временно кэшировать результаты запросов БД.

Создание тестовых данных в MySQL

Подключитесь к MySQL как администратор. Введите root-пароль MySQL.

mysql -u root -p

Вы получите доступ к командной строке MySQL.

Создайте тестовую БД и выберите ее:

CREATE DATABASE mem_test;
USE mem_test;

Создайте пользователя по имени test с паролем testing123, у которого будет доступ к тестовой базе данных:

GRANT ALL ON mem_test.* TO test@localhost IDENTIFIED BY 'testing123';

Теперь нужно создать простую таблицу и добавить в нее данные. Таблица будет называться sample_data.

CREATE TABLE sample_data (id int, name varchar(30));
INSERT INTO sample_data VALUES (1, "some_data");

Тестовые данные готовы. Можно закрыть MySQL:

exit

Создание сценария PHP для кэширования данных MySQL

Теперь можно написать еще один сценарий PHP, который будет имитировать PHP-приложение в производстве.

Сценарий будет искать данные в memcached и возвращать их, если они там есть. Если он не найдет данные, он запросит их из самой БД, а затем сохранит результаты в memcached для будущих запросов.

Создайте PHP-сценарий database_test.php в корневом каталоге:

sudo nano /var/www/html/database_test.php

Начинается он так же, как предыдущий сценарий. Создайте экземпляр memcached и укажите порт.

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
?>

Далее нужно определить, как PHP будет подключаться к базе данных MySQL. Укажите учетные данные пользователя и тестовую БД:

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
mysql_connect("localhost", "test", "testing123") or die(mysql_error());

mysql_select_db("mem_test") or die(mysql_error());

?>

Затем создайте запрос, который извлечет данные из таблицы. Эти данные будут помещены в переменную $query.

Затем нужно создать переменную $querykey, в которой будет храниться ключ, с помощью которого memcached сможет сослаться на информацию.

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

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());
$query = "SELECT ID FROM sample_data WHERE name = 'some_data'";

$querykey = "KEY" . md5($query);

?>

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

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());
$query = "SELECT name FROM sample_data WHERE id = 1";
$querykey = "KEY" . md5($query);
$result = $mem->get($querykey);
?>

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

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());
$query = "SELECT name FROM sample_data WHERE id = 1";
$querykey = "KEY" . md5($query);
$result = $mem->get($querykey);
if ($result) {

print "<p>Data was: " . $result[0] . "</p>";


print "<p>Caching success!</p><p>Retrieved data from memcached!</p>";


}

?>

Если же результата в кэше нет, сценарий отправит БД запрос. Результат будет храниться в переменной $result в виде массива.

После получения результата запроса нужно добавить его в memcached, чтобы данные были там и могли использоваться в дальнейших запросах. Для этого добавьте в memcached ключ для ссылки на эти данные (он создан в переменной $querykey), а также сами данные (хранящиеся в переменной $result из запроса MySQL) и укажите время кэширования в секундах.

Теперь memcached будет кэшировать контент в течение 10 секунд. Для тестирования этого достаточно, но в реальных сценариях, скорее всего, будет полезно кэшировать контент дольше (около 10 минут).

Затем нужно вывести сообщение с результатом запроса. Для этого добавьте блок else.

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);
mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());
$query = "SELECT name FROM sample_data WHERE id = 1";
$querykey = "KEY" . md5($query);
$result = $mem->get($querykey);
if ($result) {
print "<p>Data was: " . $result[0] . "</p>";
print "<p>Caching success!</p><p>Retrieved data from memcached!</p>";
} else {

$result = mysql_fetch_array(mysql_query($query)) or die(mysql_error());


$mem->set($querykey, $result, 10);


print "<p>Data was: " . $result[0] . "</p>";


print "<p>Data not found in memcached.</p><p>Data retrieved from MySQL and stored in memcached for next time.</p>";


}

?>

Теперь сценарий полностью готов. Он попытается найти данные в кэше memcached и вывести их. Если в кэше данных не будет, он отправит запрос в БД MySQL и будет хранить результат в течение 10 секунд.

Тестирование сценария

Теперь попробуйте запустить сценарий в браузере.

http://server_domain_name_or_IP/database_test.php

При первом посещении страницы вы увидите такое сообщение:

Data was: some_data
Data not found in memcached.
Data retrieved from MySQL and stored in memcached for next time.

Обновите страницу в течение 10 секунд, и на странице появится другой результат:

Data was: some_data
Caching success!
Retrieved data from memcached!

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

Заключение

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

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

Читайте также: Использование Memcached с Ruby on Rails на Ubuntu 12.04 LTS

Tags: ,