Файловый кэш на сайте работает до поры. Пока страниц немного, каталог /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 или внешний адрес, хранилище слушает интернет, и дальше вопрос только в том, кто найдёт его первым. Снаружи то же самое проверяется попыткой подключиться к порту с другой машины.
Что сделать по шагам
- Посмотреть, ждёт ли сайт диск. Если нет — оставить файловый кэш и заняться более полезным.
- Поставить Redis, проверить, какое расширение PHP установлено на сервере, и прописать соответствующий класс в
.settings.php. - Задать
sid, если на сервере больше одного сайта. - Открыть «Настройки — Производительность» и убедиться, что тип кэша изменился.
- Ограничить
maxmemoryосознанно и посмотреть через суткиevicted_keys. - Закрыть порт: локальный адрес, защищённый режим, пароль при доступе по сети.
- Добавить хранилище в мониторинг — падение означает работу без кэша, а не аварию, и само себя не проявит.
- Решить отдельно, переносить ли туда сессии, и если да — включить разделённый режим.
Если сомневаетесь, что у вас настроено и не открыто ли лишнее, начните с экспресс-аудита сайта: он смотрит снаружи и показывает, что видно постороннему. А разбор того, как устроен кэш в Битриксе, объясняет, откуда вообще берутся эти файлы и почему их иногда приходится чистить руками.
Статья была полезна?
Частые вопросы
Что лучше для Битрикса — 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 независимо от движка, поэтому сбросы по тегам продолжают обращаться к базе. Композитные страницы тоже считаются отдельно от настройки кэша.