Кэширование в PHP: Redis, Memcached и встроенные решения
Кэширование — один из ключевых инструментов для повышения производительности веб-приложений. В PHP разработчику доступно несколько подходов: от простого файлового кэша до мощных in-memory систем, таких как Redis и Memcached. В этой статье мы подробно разберём каждый вариант, приведём примеры кода и поможем выбрать оптимальное решение для вашего проекта.
Зачем нужно кэширование?
Без кэширования каждый запрос к сайту может приводить к повторным вычислениям, запросам к базе данных или внешним API. Кэш позволяет сохранить результат дорогостоящей операции и отдавать его из быстрого хранилища. Основные сценарии использования:
- Сохранение результатов SQL-запросов (особенно агрегаций и JOIN).
- Кэширование HTML-фрагментов (например, меню, сайдбаров).
- Хранение сессий пользователей.
- Кэширование ответов внешних API.
1. Redis — король in-memory кэширования
Redis — это высокопроизводительное хранилище данных в оперативной памяти, поддерживающее структуры данных: строки, списки, хеши, множества. Для PHP существует несколько клиентов, самый популярный — predis/predis (чистый PHP) и phpredis (расширение на C).
Установка
composer require predis/predis
Пример: кэширование результата запроса к базе данных
<?php
require 'vendor/autoload.php';
use Predis\Client;
$redis = new Client([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
]);
function getUsersFromDb() {
// Имитация долгого запроса
sleep(2);
return ['user1', 'user2', 'user3'];
}
$cacheKey = 'users:all';
$cached = $redis->get($cacheKey);
if ($cached) {
$users = json_decode($cached, true);
echo "Из кэша: ";
} else {
$users = getUsersFromDb();
$redis->setex($cacheKey, 3600, json_encode($users)); // TTL 1 час
echo "Из базы: ";
}
print_r($users);
Ключевые возможности Redis:
setex()— установка ключа с временем жизни (TTL).expire()— установка TTL для существующего ключа.del()— удаление ключа.incr()— атомарное увеличение (счётчики).
2. Memcached — простота и скорость
Memcached — ещё одна популярная in-memory система, но в отличие от Redis, она поддерживает только строковые значения и не имеет встроенных структур данных. Однако для простого кэширования она работает быстрее за счёт минимализма.
Установка расширения
sudo apt install php-memcached
# или через pecl:
pecl install memcached
Пример: кэширование HTML-фрагмента
<?php
$memcached = new Memcached();
$memcached->addServer('127.0.0.1', 11211);
function renderMenu() {
// Дорогая генерация меню
return '<nav><ul><li>Главная</li></ul></nav>';
}
$menuHtml = $memcached->get('menu:main');
if ($menuHtml === false) {
$menuHtml = renderMenu();
$memcached->set('menu:main', $menuHtml, 600); // TTL 10 минут
}
echo $menuHtml;
Важно: Memcached не поддерживает TTL в секундах по умолчанию — время задаётся в секундах (целое число). Если передать 0, кэш будет храниться вечно.
3. APCu — встроенное кэширование в PHP
APCu (Alternative PHP Cache) — это расширение для кэширования данных в общей памяти одного сервера. Идеально подходит для одностраничных приложений и небольших проектов.
Установка
sudo apt install php-apcu
Пример: кэширование конфигурации
<?php
$configKey = 'app:config';
if (apcu_exists($configKey)) {
$config = apcu_fetch($configKey);
} else {
$config = parse_ini_file('config.ini');
apcu_store($configKey,