Бесплатный экспресс-аудит сайта Безопасность, SEO, AI-поиск и 152-ФЗ — отчёт с баллами за минуту Проверить сайт
Обсудить проект

Redis или memcached для сайта на Битриксе: что ставить и как не открыть наружу

Оценить статью

Файловый кэш на сайте работает до поры. Пока страниц немного, каталог /bitrix/cache/ читается с диска быстрее, чем собирается заново из базы. Когда страниц становится десятки тысяч, а посетителей — сотни одновременно, диск превращается в узкое место: сервер не считает, а ждёт.

Тогда кэш переносят в память — в Redis или memcached. Разбираем, что из этого умеет Битрикс, чем хранилища отличаются на практике и что обязательно сделать после установки, чтобы не отдать содержимое сайта наружу.

Что Битрикс умеет из коробки

В ядре лежат готовые движки кэша: файлы, memcache, memcached, APCu, Redis и Valkey. Последний появился после смены лицензии Redis и наследует тот же класс — для Битрикса это почти одно и то же хранилище.

Какой движок работает, определяется одним параметром в /bitrix/.settings.php. Вот настройка для Redis — она же пример из документации вендора:

'cache' => [
    'value' => [
        'type' => [
            'class_name' => '\Bitrix\Main\Data\CacheEngineRedis',
            'extension' => 'redis',
        ],
        'redis' => [
            'host' => '127.0.0.1',
            'port' => '6379',
        ],
        'sid' => $_SERVER['DOCUMENT_ROOT'].'#01',
    ],
],

Для memcached меняются две строки: класс CacheEngineMemcache, расширение memcache, секция memcache с портом 11211. Ключ sid разделяет кэш между сайтами на одном сервере: без него два проекта, смотрящие в одно хранилище, начнут читать чужие записи.

Проверить, что всё подхватилось, можно в административной части: «Настройки — Производительность» показывает тип кэша. Значение cacheenginenone означает, что кэша нет вообще, и об этом ниже.

Чего перенос кэша в память не делает

Три вещи, про которые обычно узнают позже, чем хотелось бы.

  • Теги кэша остаются в базе. Тегированный кэш — тот, что сбрасывается при изменении элемента инфоблока, — хранит связи в таблице b_cache_tag, независимо от движка. Нагрузка на базу от неё никуда не денется, а на больших каталогах таблица разрастается и её приходится чистить.
  • Композитный сайт считается отдельно. Готовые HTML-страницы хранятся сами по себе, в файлах или в базе, и настройка кэша их не касается.
  • Сессии — отдельная секция настроек. Перенесли кэш в Redis, а сессии остались в файлах на диске: половина дисковых операций на месте.

Redis или memcached

Если сайт новый и выбирать не из чего, берите Redis. Разница не в скорости — на типичной нагрузке сайта её не видно — а в четырёх вещах.

Расширение PHP. Для Redis есть одно живое расширение. Для memcached их исторически два: старое memcache и новое memcached поверх libmemcached. Битрикс поддерживает оба, но классы разные, и указывать в настройках надо то, что реально установлено на сервере. Половина историй «memcached стоит, а Битрикс его не видит» — именно про это.

Сериализация. Redis-движок по умолчанию берёт igbinary, если расширение есть: данные занимают меньше памяти и быстрее разбираются. Memcached по умолчанию складывает в штатный формат PHP.

Перезапуск. Memcached после рестарта пуст всегда. Redis умеет сохранять содержимое на диск и подниматься с ним. Для кэша это не критично, но первые минуты после перезапуска сайт не будет собирать всё заново под живым трафиком.

Одно хранилище на всё. В Redis складывают и кэш, и сессии. Memcached сессии тоже держит, но настраивать и мониторить два разных сервиса смысла мало.

Плюс момент, который стоит знать: после смены лицензии Redis появился форк Valkey, и в ядре Битрикса под него есть отдельный движок — CacheEngineValKeyLight. Подключается он так же, через class_name, и наследует всю логику Redis.

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

А может, вообще не нужно

Перенос кэша в память помогает не всем. Он решает две задачи: разгрузить диск и дать нескольким серверам общий кэш.

Если сайт живёт на одном сервере с NVMe, а в /bitrix/cache/ лежит пара гигабайт, файловый кэш работает прекрасно и ничего менять не надо. Признаки, что пора: высокая нагрузка ожидания ввода-вывода при живом процессоре, медленный отклик на страницах со сложными выборками, тысячи файлов в каталоге кэша и долгая его очистка. И отдельный случай — несколько веб-серверов за балансировщиком: там общий кэш нужен не ради скорости, а чтобы серверы не расходились в данных.

Главная ловушка: хранилище упало — кэша нет

Это стоит понять до того, как настройки уедут на боевой сайт. Если указанное хранилище недоступно, Битрикс не возвращается к файловому кэшу. Он подставляет пустой движок — тот самый cacheenginenone — и пишет предупреждение в журнал ошибок.

Сайт при этом работает. Просто каждая страница начинает собираться заново из базы, на каждый запрос. При сотне посетителей в минуту это заметно по нагрузке, при тысяче — база ложится, и выглядит это как внезапная авария без видимой причины: код не менялся, трафик обычный, а сервер в полке.

Поэтому две вещи обязательны. Хранилище кэша мониторится наравне с базой: доступность порта и живость процесса. И после любой правки настроек стоит заглянуть в «Настройки — Производительность» и убедиться, что тип кэша тот, который вы прописали, а не cacheenginenone.

Память и вытеснение

Второй источник странных тормозов — закончившаяся память. У Redis есть предел maxmemory и правило, что делать при его достижении. Частый вариант allkeys-lru выбрасывает самые давние записи, и кэш начинает таять: страницы, которые раньше отдавались из памяти, снова собираются из базы.

Посмотреть, что происходит, можно двумя командами:

redis-cli info memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy'
redis-cli info stats | grep -E 'evicted_keys|keyspace_hits|keyspace_misses'

Растущий evicted_keys означает, что памяти мало. Соотношение попаданий и промахов показывает, работает кэш или только делает вид.

Сессии: где они лежат и что будет при перезапуске

Хранение сессий настраивается в той же .settings.php, но в своей секции. Битрикс умеет держать их в файлах, в базе, в Redis и в memcache.

'session' => [
    'value' => [
        'mode' => 'default',
        'handlers' => [
            'general' => [
                'type' => 'redis',
                'host' => '127.0.0.1',
                'port' => '6379',
            ],
        ],
    ],
],

У такой схемы есть известное неудобство: перезапустили хранилище — разлогинили всех. Поэтому в ядре есть разделённый режим, где данные авторизации отделены от остального содержимого сессии и могут храниться в зашифрованных куках, а всё прочее — в Redis. Перезапуск хранилища тогда не выбрасывает людей из личных кабинетов и из корзины.

Теперь безопасность, и это не формальность

Кэш сайта — это не абстрактные байты. Там лежат куски разметки с данными, результаты выборок, а если туда же отправлены сессии — идентификаторы авторизованных пользователей. Доступ к хранилищу означает доступ к содержимому сайта и возможность войти под чужой учётной записью.

Redis. Порт 6379. Современные сборки по умолчанию слушают только локальный адрес и включают защищённый режим, но эти настройки часто меняют, когда поднимают второй сервер, и забывают вернуть ограничение. Что должно быть:

  • bind 127.0.0.1, если Redis и сайт на одной машине;
  • protected-mode yes;
  • requirepass с длинным паролем, если хранилище доступно по сети, плюс фильтрация на межсетевом экране;
  • переименованные или отключённые опасные команды, прежде всего CONFIG и FLUSHALL.

Открытый наружу Redis без пароля — это не теоретический риск. Через него читают содержимое кэша целиком, а при правах на запись в файловой системе используют для закрепления на сервере. Такие хосты находят массовым сканированием в тот же день, когда их открывают.

Memcached. Порт 11211, аутентификации в привычном виде нет вовсе. Главная историческая беда — поддержка UDP: в 2018 году открытые серверы использовали для усиления DDoS-атак, уязвимость известна как CVE-2018-1000115. С версии 1.5.6 UDP выключен по умолчанию, но сборки в дистрибутивах иногда возвращают его обратно параметром запуска, поэтому проверять надо на своём сервере, а не по номеру версии.

Проверка занимает одну команду. На сервере:

ss -ltn | grep -E '6379|11211'

Если в выводе стоит 127.0.0.1 — хорошо. Если 0.0.0.0 или внешний адрес, хранилище слушает интернет, и дальше вопрос только в том, кто найдёт его первым. Снаружи то же самое проверяется попыткой подключиться к порту с другой машины.

Что сделать по шагам

  1. Посмотреть, ждёт ли сайт диск. Если нет — оставить файловый кэш и заняться более полезным.
  2. Поставить Redis, проверить, какое расширение PHP установлено на сервере, и прописать соответствующий класс в .settings.php.
  3. Задать sid, если на сервере больше одного сайта.
  4. Открыть «Настройки — Производительность» и убедиться, что тип кэша изменился.
  5. Ограничить maxmemory осознанно и посмотреть через сутки evicted_keys.
  6. Закрыть порт: локальный адрес, защищённый режим, пароль при доступе по сети.
  7. Добавить хранилище в мониторинг — падение означает работу без кэша, а не аварию, и само себя не проявит.
  8. Решить отдельно, переносить ли туда сессии, и если да — включить разделённый режим.

Если сомневаетесь, что у вас настроено и не открыто ли лишнее, начните с экспресс-аудита сайта: он смотрит снаружи и показывает, что видно постороннему. А разбор того, как устроен кэш в Битриксе, объясняет, откуда вообще берутся эти файлы и почему их иногда приходится чистить руками.

Статья была полезна?

Оцените первым — так другие читатели поймут, стоит ли читать

Частые вопросы

Что лучше для Битрикса — Redis или memcached?

Для нового проекта Redis: одно живое расширение PHP вместо двух, компактная сериализация через igbinary, содержимое переживает перезапуск, в одном хранилище можно держать и кэш, и сессии. Если memcached уже стоит и работает, менять его ради этого не нужно.

Где в Битриксе настраивается тип кэша?

В файле /bitrix/.settings.php, секция cache. В параметре type указывается класс движка и требуемое расширение PHP, рядом — секция с адресом и портом хранилища. После правки тип кэша видно в административной части, в разделе «Настройки — Производительность».

Что будет, если Redis упадёт?

Сайт продолжит работать, но без кэша: Битрикс не переключается обратно на файлы, а подставляет пустой движок и пишет предупреждение. Каждая страница начинает собираться из базы заново, и при заметном трафике база быстро уходит в перегрузку. Поэтому хранилище кэша надо мониторить наравне с базой.

Нужно ли переносить кэш в память, если сайт один и небольшой?

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

Чем опасен открытый порт Redis или memcached?

В кэше лежат данные сайта, а если туда же отправлены сессии — идентификаторы авторизованных пользователей, по которым можно войти под чужой учётной записью. Redis без пароля вдобавок позволяет писать данные, а открытый memcached с включённым UDP используют для усиления DDoS-атак. Проверяется командой ss -ltn: хранилище должно слушать 127.0.0.1.

Перенос кэша в Redis уберёт нагрузку на базу?

Частично. Теги кэша Битрикс хранит в таблице b_cache_tag независимо от движка, поэтому сбросы по тегам продолжают обращаться к базе. Композитные страницы тоже считаются отдельно от настройки кэша.