Оптимизация highload-проекта на Битрикс — это не набор случайных твиков, а последовательность измеримых шагов: сначала находим узкое место, затем устраняем его и снова замеряем. Ниже — рабочий порядок действий, который мы применяем на проектах с тысячами RPS.
С чего начинать: найти узкое место, а не гадать
Главная ошибка при оптимизации — начинать с тюнинга того, что попалось под руку. Пока вы не измерили, где именно теряется время, любая правка — лотерея. Начните с монитора производительности Битрикс (/bitrix/admin/perfmon_panel.php) и панели разработчика внизу страницы, которая показывает время генерации, число хитов кэша и количество SQL-запросов.
Типовые узкие места распределяются предсказуемо:
- База данных — тяжёлые выборки, отсутствие индексов,
filesort, N+1 в компонентах каталога; - PHP — неоптимальные компоненты без кэша, регулярные пересчёты, тяжёлые события;
- ввод-вывод — управляемый кэш на диске, логи, сессии в файлах;
- внешние вызовы — синхронные обращения к 1С, платёжным шлюзам, API поставщиков.
Оценка масштаба: BUS и базовые настройки
Прежде чем лезть в код, проверьте очевидное. Запустите тест производительности (Bitrix Universal Score) в Настройки → Производительность → Панель производительности и сверьте показатели конфигурации с рекомендуемыми. Часто половина проблем — это неверные значения в PHP и MySQL.
| Параметр | Рекомендация для highload |
|---|---|
opcache.enable | On, с достаточным memory_consumption (256–512 МБ) |
opcache.revalidate_freq | Больше 0 на prod, чтобы не проверять файлы на каждом хите |
realpath_cache_size | 4096K и выше при большом числе файлов ядра |
| Кэш Битрикс | Redis/Memcached вместо файлового |
| Сессии | В Redis, а не в файлах, при нескольких нодах |
Отдельно убедитесь, что включён opcache с прогретым кэшем: на первом хите после деплоя генерация всегда медленнее — это норма, а не деградация.
Кэширование: главный рычаг ускорения
На Битрикс кэш даёт больше всего эффекта при минимальных рисках. Работайте по трём уровням:
- Кэш компонентов — включайте для всех тяжёлых компонентов каталога, меню, новостей. Не забывайте про кэшируемые тегированным кэшем выборки, чтобы сброс шёл точечно.
- Автокэширование — глобальный флаг в
Настройки → Автокэширование. На проде должен быть включён всегда. - Композитный сайт — вынос статической части страницы в отдельный кэш и отдача её до старта ядра.
Для кастомного кода используйте \Bitrix\Main\Data\Cache и TaggedCache. Тегируйте кэш идентификаторами инфоблока (iblock_id_XX), чтобы при изменении элемента сбрасывался только связанный кэш, а не весь сайт.
База данных: индексы и тяжёлые запросы
Когда кэш выжат, узким местом почти всегда остаётся MySQL. Включите лог медленных запросов (slow_query_log) с порогом long_query_time = 0.5 и соберите топ по частоте и суммарному времени через pt-query-digest или монитор Битрикс.
Что проверять в первую очередь:
EXPLAINтяжёлых выборок — ищитеtype: ALL(full scan) иUsing filesort;- индексы на пользовательских свойствах инфоблоков и фильтруемых полях;
- размер
innodb_buffer_pool_size— под данные и индексы должно хватать памяти; - умные фильтры каталога — включённый facet-индекс резко снижает нагрузку.
Для больших каталогов переводите инфоблоки в режим Инфоблоки 2.0 — отдельные таблицы свойств вместо общей b_iblock_element_property дают кратный выигрыш на выборках.
Код и события: где утекает время
Медленный код чаще всего прячется в обработчиках событий и агентах. Проверьте:
- обработчики
OnBeforeIBlockElementUpdate,OnSaleOrderSaved— синхронные обращения к внешним системам блокируют пользователя; - агенты (
CAgent), выполняющиеся на хите, — переносите на cron; - отправку писем и уведомлений — только через очередь, не в момент запроса.
Тяжёлые операции обмена с 1С, генерацию документов и рассылки выносите в фоновые задачи. Для этого используйте очереди и cron-агенты вместо агентов на хите (define('BX_CRONTAB', true)). Пользователь не должен ждать, пока отработает интеграция.
Когда одной ноды мало: масштабирование
Если вертикальный тюнинг исчерпан, переходят к горизонтальному масштабированию через модуль cluster. Он даёт репликацию MySQL master-slave, распределение кэша, разделение веб-нод и балансировку.
| Компонент | Решение при масштабировании |
|---|---|
| Веб-ноды | Несколько PHP-нод за балансировщиком (nginx/HAProxy) |
| Сессии и кэш | Общий Redis/Memcached для всех нод |
| БД | Master для записи, slave-реплики для чтения |
| Файлы | Общее хранилище или синхронизация upload-каталога |
Кластер оправдан, когда одна нода упирается в CPU при уже оптимизированном коде и кэше. Масштабировать неоптимизированный проект — значит платить за железо вместо исправления причины.
Итог
Оптимизация highload-проекта на Битрикс — это цикл «измерил → нашёл узкое место → устранил → перепроверил». Порядок обычно один и тот же: базовые настройки PHP и MySQL, кэш и композит, индексы и тяжёлые запросы, вынос фоновых операций из хита и только затем — кластер. Прыгать сразу к железу без диагностики бессмысленно и дорого.
Мы в B2Bsite проходим этот путь на проектах с высокой посещаемостью: находим реальные узкие места под нагрузочным тестом, приводим базу и кэш в порядок и, где нужно, разворачиваем отказоустойчивый кластер. Если проект перестаёт держать нагрузку — поможем разобрать причину и построить архитектуру, которая выдержит рост.
Частые вопросы
С чего начать оптимизацию, если сайт просто «тормозит»?
С измерения. Откройте монитор производительности и панель разработчика, посмотрите время генерации и число SQL-запросов на тяжёлых страницах. Только увидев цифры, выбирайте, что чинить в первую очередь.
Насколько сильно помогает кэш на Битрикс?
Обычно это самый большой рычаг с наименьшим риском. Включённое автокэширование, кэш компонентов и композит на типовом каталоге сокращают время генерации в разы. Начинать оптимизацию стоит именно отсюда.
Что даёт перевод инфоблоков в режим 2.0?
Свойства элементов хранятся в отдельных таблицах, а не в общей b_iblock_element_property. На больших каталогах выборки по свойствам ускоряются кратно, а умный фильтр работает через facet-индекс.
Когда пора переходить на кластер?
Когда одна нода упирается в CPU или БД при уже оптимизированном коде и включённом кэше. Масштабировать неоптимизированный проект дорого и не решает корневую проблему.
Почему первый хит после деплоя всегда медленнее?
После сброса opcache и кэша ядро заново компилирует файлы и наполняет кэш. Это нормальный прогрев. Оценивайте производительность на прогретом кэше, а не сразу после релиза.
Можно ли кэшировать страницы с ценами и остатками?
Да, но с тегированным кэшем и сбросом по событиям обмена с 1С. Длинное время жизни кэша для остатков ведёт к рассинхрону. Статику кэшируйте надолго, динамику — точечно по тегам.
Куда выносить тяжёлые операции обмена с 1С?
В фоновые задачи по cron, а не в обработчики событий на хите. Синхронный вызов внешней системы в момент запроса блокирует пользователя и роняет отзывчивость сайта.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.