Существует множество способов увеличения скорости работы сайта и снижения нагрузки на сервер за счёт использования разных вариантов кеширования. В предыдущей статье представлен их краткий обзор. В этой серии материалов рассмотрим метод, который даст максимальную производительность при минимальных затратах на его настройку.
- Drupal 8 и Redis, часть 1: прямой доступ NGINX к Redis
- Drupal 8 и Redis, часть 2: обзор модуля и настройка NGINX
- Drupal 8 и Redis, часть 3: очистка внешнего кеша
Идея, которая стоит за этим решением не новая, её высказывали неоднократно, её суть — хранить данные в памяти, в быстром key-value хранилище Redis или Memcached и читать их оттуда напрямую из Nginx без обращений к PHP.
Схематично это выглядит так:

Nginx получает запрос страницы и сначала пытается получить данные из Redis, если страницы нет в кеше Redis, запрос передаётся в PHP (в Drupal).
Рассмотрим подробнее как реализовать эту схему.
Nginx
Для того, чтобы NGINX мог взаимодействовать с Redis, нужно подключить модуль HTTP Redis. Как это сделать подробно описывается в статье Компиляция динамических модулей для NGINX (на примере HTTP Redis). Есть более функциональный вариант — Redis2, но нам необходимо только чтение, поэтому обойдёмся более простым модулем HTTP Redis.
Drupal и Redis
Ставим на сервере Redis и используем его в качестве хранилища кеша Drupal. Это делается с помощью модуля https://www.drupal.org/project/redis.
Посмотрим как выглядят записи. В качестве GUI для Redis используем, например, Keylord:

Слева перечень ключей, справа значения. Записи относящиеся к кешу страниц (именно они нас интересует), будут содержать в названии ключа:
render:http
Вот пример полного ключа:
drupal.redis.8.3.7..3f62575ace1138c5777536543445081669d32a76a2a8d6ee514ca459bd0c89f8:render:http://drupalvm.dev/mypage:html
Значение поля Data:

Страница хранится в виде объекта Response в сериализованном виде. Nginx не может прочитать это.
Redis Page Cache
Будем делать в Redis собственные записи, в которых сохранять html-страницы, эти записи станут доступны для чтения из Nginx.
Redis будет содержать два типа записей:
- Стандартный кеш Drupal
- Записи, где в качестве значения хранятся html-страницы. Назовём их Redis Page Cache

Для сохранения страниц в собственном кеше (Redis Page Cache), можно использовать, как минимум, два подхода:
- StackMiddleware
- Добавить обработчик на одно из событий, которые срабатывают во время отдачи страницы от Drupal
Я выбрал второй вариант и событие TERMINATE.
Ссылки по теме:
The HttpKernel Component
The Drupal 8 render pipeline
Итак, у нас получается, что один и тот же Redis используется в двух качествах: в нём хранится стандартный кеш Drupal и Redis выступает в качестве внешнего кеша страниц.
Для Redis Page Cache будем использовать ключи вида: rpcache:url. Пример записи:
