Кэширование в PHP: Redis, Memcached и встроенные решения для ускорения сайта

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Зачем нужно кэширование в PHP?

Любое современное веб-приложение на PHP сталкивается с проблемой производительности. Каждый запрос к базе данных, чтение файлов конфигурации или рендеринг сложного HTML-шаблона отнимает время и ресурсы сервера. Кэширование — это техника, которая позволяет сохранять результаты дорогостоящих операций в быстром хранилище, чтобы при повторном запросе отдавать готовые данные мгновенно.

В PHP существует несколько уровней кэширования: от встроенного кэширования байт-кода (OPcache) до распределённых систем вроде Redis и Memcached. В этой статье мы разберём, как и когда применять каждый из этих инструментов, чтобы ваш сайт работал быстрее, выдерживал больше нагрузки и экономил ресурсы.

Встроенные решения: OPcache и APCu

Прежде чем подключать внешние сервисы, стоит обратить внимание на то, что PHP предлагает «из коробки». Два ключевых механизма — OPcache и APCu — могут дать значительный прирост производительности без установки дополнительного ПО.

OPcache: Кэширование байт-кода

Каждый раз, когда PHP исполняет скрипт, он компилирует его в байт-код (opcode). OPcache сохраняет этот байт-код в общей памяти, что позволяет пропустить стадию компиляции при последующих запросах. Это особенно эффективно для фреймворков (Laravel, Symfony) и CMS (WordPress, Drupal), где на каждый запрос загружаются десятки файлов.

Настройка в php.ini:

opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60

Рекомендуется включать OPcache на всех production-серверах. Это, пожалуй, самый простой способ ускорить PHP-приложение на 20–40%.

APCu: Кэширование пользовательских данных

APCu (Alternative PHP Cache) предоставляет простой интерфейс для хранения произвольных данных в общей памяти. В отличие от OPcache, который кэширует код, APCu хранит результаты вычислений: данные из БД, сериализованные объекты, HTML-фрагменты.

Пример кэширования результата SQL-запроса:

// Сохраняем данные на 300 секунд
$key = 'users_list';
$data = apcu_fetch($key, $success);

if (!$success) {
    $data = $db->query("SELECT * FROM users")->fetchAll();
    apcu_store($key, $data, 300);
}

return $data;

APCu идеально подходит для одностраничных приложений или проектов с одним сервером. Однако его данные хранятся локально, и при использовании нескольких серверов (горизонтальное масштабирование) вам понадобится распределённое решение.

Memcached: Простое и быстрое распределённое кэширование

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

Установка расширения PHP:

pecl install memcached

Пример подключения и работы:

$memcached = new Memcached();
$memcached->addServer('localhost', 11211);

$key = 'article_123';
$cached = $memcached->get($key);

if ($cached === false) {
    $article = getArticleFromDB(123);
    $memcached->set($key, $article, 3600); // кэш на 1 час
} else {
    $article = $cached;
}

Memcached не поддерживает сложные структуры данных (только строки и бинарные объекты), но он отлично справляется с задачей «классического» кэша: кладите данные по ключу, забирайте по ключу. Важно помнить, что Memcached не имеет встроенной персистентности — при перезагрузке сервера все данные теряются.

Redis: Мощный и гибкий инструмент для кэширования

Redis — это не просто кэш, а полноценное хранилище данных в памяти с поддержкой персистентности, транзакций и сложных структур (списки, множества, хеши, очереди). Для PHP-разработчика Redis открывает возможности, выходящие далеко за рамки обычного кэширования.

Установка через Composer (predis/predis) или pecl (redis):

pecl install redis

Пример: кэширование с истечением времени и проверкой существования:

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

$cacheKey = 'user_profile_42';
$profile = $redis->get($cacheKey);

if (!$profile) {
    $profile = fetchProfileFromDB(42);
    $redis->setex($cacheKey, 600, serialize($profile)); // живёт 10 минут
} else {
    $profile = unserialize($profile);
}

Дополнительные возможности Redis:

  • Счётчики: $redis->incr('visits'); — атомарное увеличение числа просмотров.
  • Очереди задач: $redis->lPush('queue', $task); — управление фоновыми задачами.
  • Сессии: хранение PHP-сессий в Redis для масштабирования приложения на несколько серверов.
  • Персистентность: Redis может сохранять данные на диск (RDB или AOF), что защищает от потери информации при аварийном отключении.

Если вам нужно не только ускорить сайт, но и организовать pub/sub, рейтинги, лидерборды или сессионное хранилище — Redis станет лучшим выбором.

Сравнение и рекомендации по выбору

Чтобы выбрать подходящее решение, ответьте на три вопроса:

  1. Сколько серверов у вас в продакшене? Один — подойдёт APCu. Несколько — Memcached или Redis.
  2. Нужна ли персистентность? Нет — Memcached или Redis без сохранения. Да — Redis с AOF.
  3. Нужны ли сложные структуры данных? Нет — Memcached. Да — Redis.

В большинстве современных PHP-проектов стандартом де-факто стал Redis

Блоги

Рекомендаций по книгам