Перейти к содержимому

Кэш меню - разрастание каталога, тяжёлые запросы, настройка

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

Что нужно знать заранее

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

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

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

Шаги

  1. Посмотреть размер каталога кэша меню и общее число файлов в нём.
  2. Отключить выделение текущего пункта там, где оно не нужно самому оформлению.
  3. Вынести выборки из шаблона меню в отдельный файл динамических пунктов раздела.
  4. Проверить время сборки страницы с меню и без него на копии сайта.
  5. Добавить каталог кэша меню в наблюдение за свободным местом на диске.

Решение

Смотрим размер и число файлов кэша меню:

Окно терминала
du -sh /home/bitrix/www/bitrix/managed_cache/*/*/menu 2>/dev/null | sort -h | tail -5
find /home/bitrix/www/bitrix/managed_cache -path '*menu*' -type f | wc -l
# сотни тысяч мелких файлов - обычная картина на сайте с большим каталогом

Замер объясняет и место на диске, и медленное резервное копирование. Копия сайта с миллионом мелких файлов собирается часами, а сами файлы весят меньше, чем время на их обход.

Отключаем выделение текущего пункта:

$APPLICATION->IncludeComponent('bitrix:menu', 'top', [
'CACHE_SELECTED_ITEMS' => 'N', // не хранить отдельный кэш под каждую страницу
'CACHE_TIME' => 3600,
]);
// выделение переносят на клиент, если оно нужно только для оформления

Отдельный кэш под каждую страницу нужен ровно для одного: подсветить активный пункт. Если подсветку делает разметка или скрипт на клиенте, отдельные варианты кэша не нужны вовсе.

Выносим выборку из шаблона меню:

// /catalog/.left.menu_ext.php - динамические пункты меню
$res = CIBlockSection::GetList(['SORT' => 'ASC'], ['IBLOCK_ID' => 5, 'DEPTH_LEVEL' => 1]);
while ($section = $res->GetNext()) {
$aMenuLinksExt[] = [$section['NAME'], $section['SECTION_PAGE_URL'], [], [], ''];
}
$aMenuLinks = array_merge($aMenuLinks, $aMenuLinksExt); // дополняем, а не заменяем

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

Чистим разросшийся каталог:

Окно терминала
find /home/bitrix/www/bitrix/managed_cache -path '*menu*' -type f -mtime +7 -delete
# удаление старых файлов кэша безопасно: они соберутся заново по мере обхода

Проверяем, сколько времени тратит меню:

$start = microtime(true);
$APPLICATION->IncludeComponent('bitrix:menu', 'top', $params);
printf("<!-- меню собрано за %.3f c -->\n", microtime(true) - $start);
// замер ставят временно, на копии сайта, и сравнивают попадание и промах кэша

Замер отвечает на вопрос, стоит ли вообще возиться с меню. Часто оказывается, что меню собирается за миллисекунды, а тормозит соседний блок с рекомендациями товаров.

Типичные проблемы

Каталог служебного кэша занял гигабайты.

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

Резервное копирование стало занимать часы.

В резервную копию попадают сотни тысяч мелких служебных файлов кэша этого меню. Каталоги кэша исключают из состава резервной копии: они собираются заново сами.

Меню на большом каталоге собирается медленно.

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

Пункты меню обновились не везде.

Часть вариантов кэша меню осталась старой и живёт до конца срока. После правки структуры разделов кэш меню сбрасывают целиком, а не выборочно.

Динамические пункты не появились в меню.

Массив пунктов перезаписан вместо дополнения либо отключено подключение динамических файлов меню. Пункты добавляют к уже существующему массиву меню, а не заменяют его.

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

Можно ли вообще отключить кэш меню?

Можно, но тогда выборки пойдут на каждой странице. Обычно выгоднее оставить кэш и сократить число его вариантов.

Почему в каталоге кэша так много папок?

Файлы раскладываются по подкаталогам, чтобы не упираться в ограничения файловой системы. Это нормально: смотреть надо на общий объём и число файлов.

Опасно ли удалять файлы кэша меню руками?

Нет, они пересоберутся при следующем показе страницы. Опасно удалять их в час пик: сборка ляжет на посетителей.

Как выделить активный пункт без отдельного кэша?

Сравнить адрес пункта с текущим адресом на клиенте или в шаблоне после получения кэша. Тогда один вариант кэша годится для всех страниц.

Влияет ли меню на скорость первой страницы?

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

Смежное

Первоисточник