Кэширование данных в маркетплейсе — это не опциональная оптимизация «на потом», а базовое архитектурное решение, которое закладывается ещё на этапе проектирования. Без него платформа с тысячами товаров, десятками фильтров и живыми ценами начинает «ложиться» под нагрузкой уже на старте. В этой статье — конкретные стратегии, инструменты и правила инвалидации кэша, которые мы применяем в реальных проектах.
Почему маркетплейс особенно чувствителен к производительности
Маркетплейс — это высоконагруженная система с несколькими типами пользователей: покупатели, продавцы, администраторы. Каждый запрос к каталогу может тянуть за собой десятки JOIN-запросов к базе данных: категории, атрибуты, остатки, цены, рейтинги, отзывы. При 500 одновременных пользователях это означает тысячи запросов в секунду к БД — без кэша база просто не справится.
Помимо нагрузки есть ещё одна проблема: время ответа. Google и Яндекс учитывают Core Web Vitals при ранжировании. Если страница каталога отдаётся за 3–4 секунды — конверсия падает, а позиции в поиске снижаются. Правильно настроенный кэш сокращает время ответа с секунд до миллисекунд.
Три уровня кэширования: где что хранить
Кэш в маркетплейсе работает на нескольких уровнях одновременно. Смешивать их или игнорировать один из них — значит получить узкое место в неожиданном месте.
Уровень 1 — CDN и HTTP-кэш
Статические ресурсы (изображения, JS, CSS) и страницы с низкой частотой обновления кэшируются на уровне CDN. Для маркетплейса сюда попадают: главная страница, страницы категорий без персонализации, карточки товаров с редко меняющимися данными. Заголовки Cache-Control и ETag управляют временем жизни и инвалидацией. Это самый дешёвый вид кэша — нагрузка не доходит до серверов вообще.
Уровень 2 — серверный кэш (Redis / Memcached)
Здесь хранятся результаты тяжёлых запросов: дерево категорий, агрегированные фильтры, топ товаров, данные продавца. Redis — де-факто стандарт для маркетплейсов: поддерживает структуры данных (хэши, списки, sorted sets), pub/sub для инвалидации и персистентность. Memcached проще и быстрее при простом key-value, но не даёт гибкости Redis.
Уровень 3 — кэш на уровне приложения
In-memory кэш внутри сервиса (например, через Caffeine в Java или встроенный кэш в Node.js). Хранит данные, к которым обращаются сотни раз в секунду: конфигурации, справочники, настройки комиссий. Время жизни — секунды или минуты. Главный риск — расхождение данных между инстансами при горизонтальном масштабировании.
Стратегии кэширования: выбор зависит от типа данных
Не существует универсальной стратегии. Для маркетплейса данные делятся на несколько групп с разными требованиями к актуальности:
| Тип данных | Частота изменений | Стратегия | TTL |
|---|---|---|---|
| Дерево категорий | Редко (часы) | Cache-Aside + инвалидация по событию | 1–6 часов |
| Карточка товара | Средне (минуты) | Cache-Aside или Write-Through | 5–30 минут |
| Цена и остаток | Часто (секунды) | Short TTL или Read-Through с инвалидацией | 10–60 секунд |
| Результаты поиска | Зависит от запроса | Cache-Aside по хэшу запроса | 1–5 минут |
| Корзина и сессия | Постоянно | Не кэшировать / только сессионный кэш | — |
Cache-Aside (ленивая загрузка) — приложение само проверяет кэш, при промахе идёт в БД и записывает результат. Самая распространённая стратегия: проста в реализации, не нагружает кэш незапрошенными данными.
Write-Through — запись идёт одновременно в кэш и в БД. Данные всегда актуальны, но запись медленнее. Подходит для карточек товаров, где важна консистентность.
Read-Through — кэш сам обращается к БД при промахе. Логика вынесена из приложения, удобно при использовании специализированных кэш-провайдеров.
Инвалидация кэша: самая сложная часть
Есть старая шутка в программировании: в Computer Science есть только две по-настоящему сложные задачи — именование переменных и инвалидация кэша. В маркетплейсе это не шутка, а боль.
Типичная проблема: продавец обновил цену, но покупатель ещё 10 минут видит старую. Или товар закончился, а карточка отображает «в наличии». Это не только UX-проблема, но и юридический риск.
Рабочие подходы к инвалидации:
- Event-driven инвалидация — при изменении сущности (товар, цена, остаток) публикуется событие в очередь (Kafka, RabbitMQ), подписчики сбрасывают нужные ключи. Самый надёжный способ для критичных данных.
- Tag-based инвалидация — кэш-записи помечаются тегами (например,
product:1234). При обновлении товара сбрасываются все записи с этим тегом: карточка, поисковая выдача, блок «похожие товары». - TTL с коротким сроком жизни — для данных, где небольшая задержка допустима. Просто, но неэффективно для часто меняющихся данных: либо кэш протухает слишком быстро, либо данные устаревают.
- Версионирование ключей — к ключу добавляется версия сущности. При обновлении версия меняется, старый ключ автоматически становится «мёртвым» и вытесняется по LRU.
Типичные ошибки при кэшировании в маркетплейсе
За годы работы над проектами в области разработки маркетплейса мы видели одни и те же грабли:
- Кэширование персонализированного контента как публичного. Если страница каталога содержит персональные скидки или историю просмотров — её нельзя класть в общий CDN-кэш. Результат: один пользователь видит данные другого.
- Отсутствие прогрева кэша. После деплоя или сброса кэша все запросы идут в БД одновременно — «thundering herd». Решение: фоновый прогрев критичных ключей до открытия трафика.
- Кэширование ошибок. Если БД вернула ошибку, а приложение закэшировало пустой ответ — пользователи будут видеть «нет товаров» даже после восстановления БД. Ошибки кэшировать нельзя или с минимальным TTL в 5–10 секунд.
- Игнорирование размера кэша. Redis без настройки
maxmemory-policyпри заполнении начинает отдавать ошибки. Нужно явно задавать политику вытеснения (обычноallkeys-lruдля маркетплейса). - Один Redis на всё. Смешивать сессии, кэш и очереди в одном инстансе Redis — плохая идея. При пиковой нагрузке они конкурируют за память и CPU.
Инструменты и технологии: что выбрать
Выбор инструмента зависит от стека и требований к масштабированию:
- Redis — основной выбор для серверного кэша. Кластерный режим позволяет масштабироваться горизонтально. Redis Stack добавляет поддержку полнотекстового поиска и JSON.
- Memcached — проще Redis, подходит для простого key-value кэша без сложных структур данных.
- Varnish Cache — специализированный HTTP-кэш перед веб-сервером. Отлично справляется с кэшированием страниц каталога и ESI (Edge Side Includes) для частичного кэширования страниц.
- CDN (Cloudflare, AWS CloudFront, Fastly) — для статики и кэширования на уровне edge. Cloudflare Workers позволяют реализовать логику инвалидации прямо на CDN.
- Встроенные решения фреймворков — Laravel Cache, Django Cache Framework, Spring Cache — удобны для старта, но при росте нагрузки требуют замены на Redis-кластер.
Часто задаваемые вопросы
Как понять, что кэширование настроено правильно?
Ключевые метрики — hit rate (доля запросов, обслуженных из кэша) и latency. Нормальный hit rate для каталога маркетплейса — от 70% и выше. Если hit rate ниже 50% — либо TTL слишком короткий, либо кэшируются данные с высокой уникальностью запросов (например, поиск с опечатками). Мониторьте через Redis INFO stats или встроенные дашборды (RedisInsight, Grafana + redis_exporter).
Стоит ли кэшировать результаты поиска в маркетплейсе?
Да, но с умом. Популярные запросы (топ-100–200 поисковых фраз) дают 60–80% трафика — их кэшировать обязательно, TTL 1–5 минут. Длиннохвостые запросы с редкими комбинациями фильтров кэшировать нецелесообразно: они занимают память, но почти никогда не переиспользуются. Используйте счётчик частоты запросов и кэшируйте только те, что встречаются чаще N раз за период.
Как кэширование влияет на актуальность цен и остатков?
Это главный компромисс. Цены и остатки — самые критичные данные с точки зрения бизнеса. Оптимальное решение: короткий TTL (10–30 секунд) плюс event-driven инвалидация при изменении. Так вы получаете защиту от пиковой нагрузки и при этом не показываете покупателям устаревшие данные дольше полуминуты. Для высокочастотных изменений (аукционы, динамическое ценообразование) кэш для цен не применяется вовсе — данные берутся напрямую из БД или in-memory хранилища.
Готовы обсудить архитектуру вашего проекта?
Кэширование — это одна из тем, которую мы прорабатываем на этапе проектирования каждого проекта. Если вы планируете разработку маркетплейса и хотите получить платформу, которая выдержит реальную нагрузку с первого дня — свяжитесь с нами. Обсудим стек, архитектуру и сроки. Телефон: +7 (977) 326-69-09, или оставьте заявку на странице arisweb.ru/kontakty.