18 октября 2017

Drupal 8 и Redis, часть 2: обзор модуля и настройка NGINX

Алексей Доронин
Руководитель, разработчик, дизайнер

В первой части мы рассмотрели основы способа, при котором NGINX напрямую сможет читать страницы из Redis. Это позволит снизить нагрузку на сервер и фантастически увеличит скорость работы сайта. Рассмотрим подробнее реализацию.

  1. Drupal 8 и Redis, часть 1: отдельный кеш в Redis
  2. Drupal 8 и Redis, часть 2: обзор модуля и настройка NGINX
  3. Drupal 8 и Redis, часть 3: очистка внешнего кеша

Схема выглядит так:

Для реализации записи и чтения нам понадобятся:

  1. Redis 
  2. Nginx c модулем HTTP Redis 
  3. Расширение PHPRedis 
  4. Модуль Redis для Drupal 
  5. Модуль 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. В этом случае:

При следующем запросе к mysite.com/mypage, Nginx должен возвратить эту страницу напрямую из Redis.

Представим ситуацию: на сайте уже есть 50 страниц, они все находятся в кеше страниц Drupal и вы хотите подключить Redis Page Cache. Подключили. Но все страницы продолжают отдаваться из Drupal (смотрим по заголовкам). Не работает? Нет, всё верно. Эти 50 страниц, уже находятся в кеше Drupal, поэтому при обращении к ним, не срабатывает механизм добавления в Redis Page Cache. Чтобы они туда попали, нужно сбросить кеш Drupal.

Настройки

Настройки модуля расположены по адресу: /admin/config/development/rpcache:

Во вкладках 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 cacheVarnishNginx + Redis Page Cache
Запросов в секунду18040424265
Время одного запроса55 ms2.474 ms2.344 ms

Nginx + Redis даже быстрее, чем Varnish. Впечатляющий результат. 

В следующей статье рассмотрим самый сложный момент — очистку кеша.