Каждый владелец маркетплейса сталкивается с одной и той же болью: когда товаров становится много, сайт начинает тормозить. Серверы залиты, база данных задыхается, а разработчики предлагают «добавить ещё один инстанс». Мы в LP Agency считаем, что это симптом системной проблемы, а не её решение.
Оценка нагрузки и требований
Прежде чем писать код, мы провели анализ:
Чтение/запись: 90% чтения (каталог, карточки, поиск), 10% записи (бронирования, заявки).
Пиковый RPS (запросов в секунду): 50 000 на чтение, 5 000 на запись.
Сезонные пики: выходные дни, вечерние часы — прирост до +30%.
Эти цифры определили наш выбор инструментов.
Кэширование — первый рубеж обороны
Внедрили многоуровневый кэш:
CDN (CloudFront) для статики: изображения, CSS, JS. Это снизило нагрузку на origin-серверы на 70%.
Микрокэширование на Nginx — для страниц поиска и каталога (TTL 1–5 секунд). Пример конфига:
text
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:100m inactive=60s;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 5s;Это позволило отдавать динамические страницы без пересчёта на бекенде.
Redis Cluster (6 нод, 32 ГБ ОЗУ каждая) — для кэширования JSON-ответов API, сессий пользователей, вычисляемых рейтингов и агрегатов. Использовали стратегию Cache-Aside для чтения и Write-Through для обновлений.
Наша система сама подберет вам исполнителей на услуги, связанные с разработкой сайта или приложения, поисковой оптимизацией, контекстной рекламой, маркетингом, SMM и PR.
Заполнить заявку
13590 тендеров
проведено за восемь лет работы нашего сайта.
Результат: время ответа API упало с 200 мс до 15 мс, загрузка CPU на бекенде сократилась на 60%.

Балансировка и горизонтальное масштабирование
Мы выбрали Nginx Ingress как балансировщик в Kubernetes. Настроили health checks, retries, rate limiting (не более 100 запросов в секунду с одного IP). Приложения сделали stateless — сессии хранятся в Redis, поэтому можно добавлять поды без привязки. Для авто-масштабирования использовали HPA (Horizontal Pod Autoscaler) на основе CPU и длины очереди запросов.
В пиковые часы система автоматически разворачивала до 10 подов, что позволяло держать 10 000 одновременных пользователей с задержкой менее 100 мс. Без авто-масштабирования нам пришлось бы закупить в 3 раза больше ресурсов.
Выбор баз данных — никакого компромисса
Применили полиглотный подход:
PostgreSQL — основная БД для транзакционных данных: пользователи, заказы, объекты недвижимости. Использовали партиционирование по месяцам и GIN-индексы для полнотекстового поиска по описаниям (на случай, если Elasticsearch недоступен).
Elasticsearch — поисковый движок. Индексируем 100 000 записей, поддерживаем синонимы, фасеты, релевантность. Время поиска — 50 мс (это критично для UX).
ClickHouse — для аналитики: храним историю просмотров, кликов, конверсий. Строим отчёты для владельцев бизнеса за считанные секунды по миллионам записей.
Redis — кэш и брокер очередей (для фоновых задач).
Пример SQL-запроса с индексами для PostgreSQL:
sql
CREATE INDEX idx_listings_city_price ON listings (city, price) WHERE status = 'active';
CREATE INDEX idx_listings_description_gin ON listings USING gin(to_tsvector('russian', description));Разделили потоки: запись идёт в PostgreSQL, чтение — через Elasticsearch и ClickHouse. Для распределения чтения настроили реплики master-slave.

Мониторинг и трассировка
Настроили Prometheus + Grafana для сбора метрик по каждому эндпоинту: RPS, латентность (p50, p95, p99), ошибки, использование CPU/RAM. Jaeger для распределённой трассировки — это позволяет видеть полный путь запроса и находить узкие места (например, медленный внешний вызов). Алерты в Slack при превышении порогов.
Заключение
Нет универсального решения, но есть проверенные паттерны: кэшируйте всё, что можно, дублируйте данные без страха перед избыточностью, и выбирайте БД под конкретную задачу. Мы не переписывали архитектуру ни разу за полгода после запуска — она выдержала 3-кратный рост трафика. Если ваш продукт начинает «тормозить» — это сигнал, что пора заняться архитектурой.