Ваш останній PHP/MySQL веб-сайті нарешті онлайн. І це круто.
Але все завантажується не так швидко як хотілося через велику кількість SQL- запитів, які виконуються щоразу, коли генерується сторінка. У вас поступово виникає відчуття, що ресурс не зможе масштабуватися під великі навантаження. І ви, швидше за все, маєте рацію.
У цьому уроці ми побачимо, як ви можете значно поліпшити швидкодію сайту, шляхом реалізації шару кешу між кодом і базою даних. Хороша новина - це досить легко і може бути зроблено протягом кількох хвилин!
Знайомимось з Memcached
Memcached-це високоефективна система кешування даних в пам'яті.
Сучасні веб-сайти та веб-додатки використовують багато даних, і це не рідкість, коли генерація однієї сторінки має в собі 20 або навіть 30 запитів SQL. Помножте цю суму на велику кількість відвідувачів і ви отримаєте перевантаження бази даних і як результат - повільну генерацію сторінки.
Інструмент, який ми будемо використовувати сьогодні, щоб поліпшити продуктивність - Memcached. Це високоефективна система кешування даних в пам'яті. Або, кажучи по-іншому, дуже швидка програма, яка запускається на сервері і використовує частину пам'яті, щоб зберігати асоціативний масив даних. Memcached може робити дві речі:
-
Зберегти значення
V
із ключемK
; -
Отримати значення
V
з ключемK
;
Це виглядає мінімалістично, але ви можете дуже багато зробити завдяки цим двом функціям. Насправді, Memcached має ще кілька функцій, але всі вони зводяться до збереження або отримання даних.
Установка Memcached на сучасних дистрибутивах Linux досить проста:
Ubuntu : sudo apt-get install memcached
Gentoo : sudo emerge install memcached
Redhat : sudo yum install memcached
Після установки, Memcached буде автоматично запускатися кожен раз, коли ваш
сервер завантажується. Ви можете задати об'єм пам'яті, зарезервований для
Memcached, поряд з іншими варіантами, в конфігураційному файлі
/etc/memcached.conf
). 64 Мб виділяється за замовчуванням. Конфігураційний
файл містить IP-адресу і порт, який буде пов'язаний з Memcached. Значення за
замовчуванням 127.0.0.1
і 11211
.
Доступ до Memcached з PHP
Ми хочемо зберігати і витягувати дані з PHP-скриптів. Це означає, що нам потрібен спосіб підключення до Memcached з PHP. Для цього ми збираємося встановити "Memcache", розширення для PHP. Як це PECL-розширення, встановлюємо з "pecl", ввівши таку команду:
sudo pecl install memcache
Є два розширення PHP, пов'язаних з Memcache : "Memcache" і "Memcached" (зверніть увагу на "d" \- у другому). Обидва дуже схожі, але перший більш "легкий". У цьому уроці ми будемо використовувати саме Memcache. Після установки, це розширення повинно бути ввімкнене. Якщо все добре, то Memcache функції будуть доступні для ваших PHP скриптів.
Як працює кешування?
Наша робота буде базуватися на наступних припущеннях:
-
витяг даних з бази даних віднімає ресурси (CPU + i/o);
-
витяг даних з бази даних займає багато часу;
-
ми часто отримувати однакові дані знову і знову.
Глобально, ми хочемо зберегти наші дані у стійкому середовищі (бази даних MySQL, наприклад). Але ми також хочемо зберігати дані таким чином, щоб це дозволяло нам отримувати їх більш ефективно, навіть якщо умови зберігання нестійкі. В результаті, ми будемо мати дві копії даних: одна буде зберігатися в MySQL, а інша - в Memcache.
Що для цього потрібно зробити:
-
Кожна операція запису (SQL INSERT та UPDATE) буде виконана в MySQL і Memcached;
-
Будь-яка операція читання (SQL SELECT) буде виконана в Memcached, і повернеться до MySQL в разі помилки.
В цей момент, ви, мабуть, бачите, які частини коду потрібно буде змінювати: у частині, де ви записуєте дані і у тій, де дані зчитуються. Якщо ваш PHP-код добре структуровано (код доступу до даних загорнуто у функції, ще краще - класи), то оновлення ресурсу буде дуже швидким. Якщо ні, то ви будете мати трохи більше роботи.
Підключення до Кеш-сервера
По-перше, давайте створимо з'єднання з Memcache-сервером. Ось код, який ви повинні використовувати в самому початку ваших PHP-скриптів:
// Константи підключення
define('MEMCACHED_HOST', '127.0.0.1');
define('MEMCACHED_PORT', '11211');
// Створення підключення
$memcache = new Memcache;
$cacheAvailable = $memcache->connect(MEMCACHED_HOST, MEMCACHED_PORT);
Ми створили з'єднання з нашим Memcache-сервер.
Зберігання даних в кеш
Давайте більш детально розглянемо процес зберігання даних.
Нехай ми маємо інтернет-магазин. У нас є скрипт, який називається
edit_product.php
, метою якого є збереження даних продукту в нашій базі
даних. Кожен з наших товарів має наступну інформацію:
-
id;
-
ім'я;
-
опис;
-
ціна.
У якийсь момент, ми запустимо INSERT або UPDATE SQL-запит в
edit_product.php
, метою якого буде занесення даних цього продукту до бази
даних MySQL. Він буде виглядати так:
// Протестували наші дані
// Обходимо ризикований char з mysql_real_escape_string()
// Зберігаємо в нашу базу даних:
$sql = "INSERT INTO products (id, name, description, price) VALUES ($id, '$name', '$description', $price)";
$querySuccess = mysql_query($sql, $db);
Як я вже згадував вище, ми хочемо зберігати дані як в нашій базі даних MySQL, так і на Memcache-сервері. Ось як це може бути реалізовано:
// Протестували наші дані
// Обходимо ризикований char з mysql_real_escape_string()
// Зберігаємо в нашу базу даних:
$sql = "INSERT INTO products (id, name, description, price) VALUES ($id, '$name', '$description', $price)";
$querySuccess = mysql_query($sql, $db);
// Записали дані в базу даних
// запишемо дані в кеш
// Метод "set" каже нашому Memcache-серверу зберігати дані з спеціальним ключем
if ($querySuccess === true)
{
// Створюємо унікальний ключ, який може буто створений пізніше
// Product + id (eg. "product_12")
$key = 'product_' . $id;
// Зберігаємо асоціативний масив, що містить дані нашої продукції
$product = array('id' => $id, 'name' => $name, 'description' => $description, 'price' => $price);
// Кажемо Memcache зберегти дані
$memcache->set($key, $product);
}
Таким чином, база даних і кеш-пам'ять містять дані про продукцію.
Отримання даних з кешу
Тепер давайте отримаємо наші дані. Продовжимо розглядати той же приклад,
скажімо, наш інтернет-магазин має скрипт, який називається product.php що
відображає певний продукт. Доступ до сторінки product.php?id=12
буде
відображати продукт, який має ідентифікатор 12.
Запустимо SELECT SQL-запит в product.php
, метою якого буде отримання даних
продукту з бази даних MySQL. Він буде виглядати так:
// Протестували наші дані
// Обходимо ризикований char з mysql_real_escape_string()
// Читаємо з бази даних:
$sql = "SELECT id, name, description, price FROM products WHERE id = " . $id;
$queryResource = mysql_query($sql, $db);
$product = mysql_fetch_assoc($queryResource);
Як ми вже говорили вище, ми хочемо по можливості отримувати наші дані з сервера Memcache. Якщо ж кеш сервер недоступний, ми просто переходимо до MySQL.
// Ініціалізуємо змінну $product
$product = null;
// Перевіряємо доступність кеш-сервера
// Змінна $cacheAvailable була ініціалізована, коли ми підключилися до сервера
if ($cacheAvailable == true)
{
// створюємо ключ, який асоціюється з даними продукту
$key = 'product_' . $id;
// Отримуємо дані з кеш-сервера
$product = $memcache->get($key);
}
// Чи потрібен нам доступ до MySQL ?
if (!$product)
{
// Протестували наші дані
// Обходимо ризикований char з mysql_real_escape_string()
// Хочемо прочитати з бази даних:
$sql = "SELECT id, name, description, price FROM products WHERE id = " . $id;
$queryResource = mysql_query($sql, $db);
$product = mysql_fetch_assoc($queryResource);
}
Ми отримали потрібні нам дані. Швидше за все це було зроблено з нашого кешу.
Висновок
Memcached може бути використаний для прискорення вашого сайту і зменшення навантаження на базу даних. Наш приклад використовував PHP і MySQL, оскільки ці технології широко використовуються, але цей принцип є універсальним і працює точно так само з багатьма іншими технологіями: C/C++, Java, Python, Ruby, Perl, .Net, MySQL, Postgres, Erlang, Lua, Lisp, Cold Fusion, Ocaml і io перераховані разом з PHP на офіційному Memcached Вікі.
Ще немає коментарів