mFilter 1.2.0 - улучшенное кеширование и скорость

mFilter 1.2.0 — Новая подсистема, которая заранее вычисляет и кэширует данные фильтров, чтобы страницы каталога открывались мгновенно с первого обращения.



Проблема



На каталогах свыше 10 000 товаров первая загрузка страницы с фильтрами — это боль. MySQL 8 тяжело переваривает запросы к большим таблицам: получить список товаров категории, посчитать значения фильтров, вычислить фасетные счётчики. На 200 000 товаров первая загрузка занимала до 60 секунд. Повторная — из кэша, быстро. Но каждый раз, когда кэш протухал или сбрасывался — опять ожидание.

Решение



Все тяжёлые вычисления выполняются заранее — в фоне, по расписанию, когда никто не ждёт. Результаты сохраняются в базу данных. Когда пользователь открывает страницу каталога — система находит готовый результат за миллисекунды вместо того, чтобы считать с нуля. Управление прогревом — через новую вкладку в админке и рекуррентное задание Scheduler.

Что кэшируется



При загрузке страницы каталога mFilter выполняет три тяжёлые операции. Теперь все три можно прогревать заранее:

  • baseIds — список всех ID товаров в категории. Результат вызова element-сниппета (msProducts, pdoResources) с returnIds. На больших каталогах это самый медленный запрос.
  • filter values — какие бренды, цвета, размеры доступны в этой категории. Используется формой фильтров (mFilterForm) для построения чекбоксов, слайдеров, цветовых свотчей.
  • suggestions — фасетные счётчики. Сколько товаров для каждого значения каждого фильтра. Те самые цифры в скобках рядом с чекбоксами: «Samsung (142)», «Красный (38)».
Все три типа хранятся в таблице mfl_cache с TTL. По умолчанию — 1 час.

Вкладка «Прогрев кэша»



В админке mFilter появилась шестая вкладка — Прогрев кэша. Здесь создаются и управляются конфигурации прогрева.

Конфигурация — это связка: какой сниппет вызывать (msProducts, pdoResources) + на каких страницах каталога. Создать можно двумя способами:

  • Вручную — нажать «Добавить конфигурацию», вставить вызов сниппета из шаблона и нажать «Распарсить». Парсер понимает Fenom, MODX-теги и JSON. Параметры заполнятся автоматически. Справа — дерево ресурсов для выбора страниц.
  • Автоматически — при первом посещении любой страницы каталога конфигурация создаётся сама. В таблице появится запись с пометкой «Авто».
Для запуска прогрева — две кнопки. «Прогреть всё» выполнит прогрев прямо сейчас в текущем запросе. «Через Scheduler» создаст фоновое задание — рекомендуется для больших каталогов, где прогрев может занять десятки минут.

Чекбокс «+ счётчики» включён по умолчанию. С ним прогреваются все три типа кэша. Без него — только baseIds.

Задание планировщика



Новый таск mfl_warmup регистрируется в Scheduler при установке пакета. По умолчанию — рекуррентный, запускается каждые 50 минут. При стандартном TTL в 1 час кэш обновляется с запасом и никогда не протухает.

Интервал и TTL подбираются под конкретный проект. Для каталога в 200 000 товаров прогрев занимает около 30 минут — соответственно, интервал нужен побольше. Для 5 000 товаров прогрев пролетает за минуту, и дефолтные 50 минут — с большим запасом.

При обновлении товарной базы (импорт цен, остатков, новых позиций) ничего делать не нужно — рекуррентный таск обновит кэш при следующем запуске. Если нужна актуальность прямо сейчас — кнопка «Через Scheduler» в админке.

Как это работает внутри



В сниппет mFilter добавлена проверка: перед вызовом element-сниппета система ищет прогретый кэш baseIds. Ключ кэша — MD5-хеш от параметров, влияющих на выборку (element, depth, where, showZeroPrice и т.д.). Параметры вроде tpl, sortby, showLog — не влияют на набор товаров и в хеш не входят.

Если кэш найден — element-сниппет не вызывается вообще. Экономия от 1 до 30 секунд в зависимости от размера категории. Если кэша нет — сниппет отрабатывает как раньше, а конфигурация для будущего прогрева создаётся автоматически.

Аналогично с формой фильтров. mFilterForm при загрузке вычисляет значения фильтров через getFilters() — этот метод уже имел встроенный кэш, но без прогрева первый вызов был тяжёлым. Теперь warmup заполняет этот кэш заранее.

Результат



Тестировалось на боевом каталоге — 200 000 товаров, 100 категорий. До прогрева первая загрузка страницы — 15–60 секунд. После прогрева — доли секунды. Полный прогрев каталога — около 30 минут в фоне через Scheduler.

Прочие улучшения в 1.2.0



  • Кэш suggestions теперь сохраняется при первом вычислении — повторные обращения берут из базы
  • Временные метки кэша хранятся в UTC — корректная работа при разных таймзонах cron и web
  • TvIndexer индексирует только TV из конфигурации фильтров, а не все TV ресурса
  • Удалён устаревший механизм прогрева через HTTP-запросы к страницам

Ссылки



Николай Савин
4 часа назад
modx.pro
78
+5
Поблагодарить автора Отправить деньги

Комментарии: 2

Николай Савин
4 часа назад
0
На данный момент кеширование отлажено только для каталогов без примененных фильтров. Такие страницы отрываются достаточно быстро. Обычно это 300-400 ms
А вот как сделать удачное кеширование страниц с примененными фильтрами я пока не знаю. Слишком большой набор вариаций и пересечений. Это называется вариативный взрыв. Хорошая новость в том, что даже с одним примененным фильтром товаров в каталоге остается не так много — и вся эта история загрузится сильно быстрее чем пустой каталог.
    Wassi Wassinen
    18 минут назад
    0
    Николай, прежде всего — вы молодец.

    А про кеширование — можно пойти по правилу Парето.
    То есть дать возможность закешировать самое частое — это «фильтры первого уровня». То есть самые базовые варианты (без выбора нескольких фильтров). Именно их используют чаще всего и именно они (после выборки всего каталога) имеют самые тяжелые запросы. Если в фильтрах есть, например: производитель, стиль и цена. Цену мы закешировать вряд ли можем (она, как правило, выбирается диапазоном). А вот производителей и стили — можем. Это снимет большую часть более тяжелых запросов с сервера (потому что выборка всё ещё довольно существенная на больших каталогах даже при выборе только производителя или только стиля). А выборка в формате «производитель + стиль» уже не такая тяжелая.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    2