В первой части мы рассмотрели основы способа, при котором NGINX напрямую сможет читать страницы из Redis. Это позволит снизить нагрузку на сервер и фантастически увеличит скорость работы сайта. Рассмотрим подробнее реализацию.
- Drupal 8 и Redis, часть 1: отдельный кеш в Redis
- Drupal 8 и Redis, часть 2: обзор модуля и настройка NGINX
- Drupal 8 и Redis, часть 3: очистка внешнего кеша
Схема выглядит так:
Для реализации записи и чтения нам понадобятся:
- Redis
- Nginx c модулем HTTP Redis
- Расширение PHPRedis
- Модуль Redis для Drupal
- Модуль Redis Page Cache (наш экспериментальный модуль) для Drupal
Начальные условия
Включён и работает модуль Redis. Настройка и установка Redis, PHPRedis, модуля Redis выходят за рамки статьи.
Модуль Redis Page Cache
Это экспериментальный модуль, пока нет реального опыта его использования https://github.com/azimut7/rpcache
Модуль сохраняет сформированные страницы сайта в Redis, набор таких записей называем Redis Page Cache. Это даёт возможность Nginx читать и возвращать их пользователю напрямую, без обращения к PHP. По сути, это внешний кеш.
Механизм срабатывания
Добавление страницы в кеш Redis Page Cache происходит, если она не найдена в кеше Drupal.
Например, идёт обращение к странице с адресом mysite.com/mypage, до этого к ней не было обращений, и её нет в кеше страниц (Page Cache) Drupal. В этом случае:
- Drupal собирает страницу и кладёт её в свой кеш
- Страница попадает в Redis Page Cache
При следующем запросе к mysite.com/mypage, Nginx должен возвратить эту страницу напрямую из Redis.
Представим ситуацию: на сайте уже есть 50 страниц, они все находятся в кеше страниц Drupal и вы хотите подключить Redis Page Cache. Подключили. Но все страницы продолжают отдаваться из Drupal (смотрим по заголовкам). Не работает? Нет, всё верно. Эти 50 страниц, уже находятся в кеше Drupal, поэтому при обращении к ним, не срабатывает механизм добавления в Redis Page Cache. Чтобы они туда попали, нужно сбросить кеш Drupal.
Настройки
Настройки модуля расположены по адресу: /admin/config/development/rpcache:
- Очищать все записи Redis Page Cache при стандартной очистке кеша Drupal
- Задать список адресов, которые не должны попадать в Redis Page Cache
- Можно задать свой префикс для именования ключей в Redis. По умолчанию все ключи именуются: "rpcache:url". Нужно не забывать, что ключ в настройках Nginx, должен соответствовать префиксу
- Пример настройки Nginx
Во вкладках Purge URLs и Clear all cache, можно удалить заданные URL из кеша и очистить все записи.
Модуль никак не затрагивает работу или записи основного кеша Drupal, который также находится в Redis. Любые действия по очистке, относятся только к записям этого модуля.
Настройка Nginx
Для доступа к Redis из Nginx нужен nginx модуль HTTP Redis.
Пример конфигурации Nginx для чтения записей из Redis:
...
location / {
try_files $uri @rpcache;
}
# Redis Page Cache url for purging, allow access only from localhost
location /rpcache/rpcache-clear {
allow 127.0.0.1;
deny all;
try_files $uri /index.php?$query_string;
}
location @rpcache {
## Disable logs (there are tons of info, warn etc when not found in cache)
error_log off;
## Header to see that page was handled by RedisPageCache
add_header X-RPCache 'HIT';
error_page 418 = @rewrite;
if ($http_cookie ~* "SESS") {
return 418;
}
if ($request_method !~ ^(GET|HEAD)$ ) {
return 418;
}
default_type text/html;
set $redis_key "rpcache:$scheme://$host$request_uri";
## 127.0.0.1 not localhost!
redis_pass 127.0.0.1:6379;;
proxy_intercept_errors on;
error_page 404 502 = @rewrite;
}
...
1. error_log off;
Если включено, все промахи от Redis будут попадать в логи. Можно настроить уровни, что отображать в логах.
2. add_header X-RPCache 'HIT';
Заголовок для дебага — видим, что страница пришла напрямую из Redis
3. Обрабатываются запросы только от анонимных пользователей (без сессий)
4. Только GET и HEAD запросы
5. Схема ключей: "rpcache:$scheme://$host$request_uri"
Префикс кеша "rpcache:" можно сменить в настройках модуля (см. выше).
6. Закрываем URL /rpcache/rpcache-clear для внешнего доступа, этот адрес нужен для очистки нашего кеша
Страницы с адресами http://drupalvm.dev/mypage и http://drupalvm.dev/mypage/, это разные страницы — слеш на конце. Чтобы была корректная обработка, нужно убедиться, что в настройках модуля Redirect стоит отметка «removing trainling slashes».
Можно посмотреть заголовки, если всё настроено правильно и страницы отдаются из Redis, они будут выглядеть примерно так:
Для сравнения, так выглядят заголовки, когда страница отдаётся из Drupal:
Быстродействие
Результаты синтетических тестов на виртуальной машине. Данные условные, но по ним хорошо видна разница в скорости.
ab -c 10 -t 30 http://drupalvm.dev/
1. Nginx + стандартный кеш Drupal 8 вынесенный в Redis
2. Drupal 8 + Varnish
3. Nginx отдаёт страницу напрямую из Redis
В виде таблицы:
Drupal, standard Redis cache | Varnish | Nginx + Redis Page Cache | |
---|---|---|---|
Запросов в секунду | 180 | 4042 | 4265 |
Время одного запроса | 55 ms | 2.474 ms | 2.344 ms |
Nginx + Redis даже быстрее, чем Varnish. Впечатляющий результат.
В следующей статье рассмотрим самый сложный момент — очистку кеша.