Исследование ёмкости · живой поиск · tazzz.ru

Ёмкость живого поиска

Сколько одновременных поисков реально тянет сервер, сколько люди простоят в очереди и где именно начнёт гореть. Ответ короткий: сегодняшний потолок — искусственный (ручная пятёрка в конфиге), физика позволяет ~150 поисков в час комфортно и ~240 в пределе, а первыми горят не сервер, а крошечные пулы прокси: 4 + 4 + 1 адрес и 4 VPN-устройства на все китайско-корейско-немецкие площадки.

Снято 27 августа 2026, прод live
Метод конфиг + код + история 60 дней + Loki 48 ч + симуляция
Железо 4 vCPU · 7,75 ГБ · HDD · один сервер
Сегодняшний спрос пик 8 поисков/час — запас ×20+
Итог

Ответы на три вопроса

Все цифры — из боевого конфига, замеров и симуляции очереди на реальных длительностях сессий; методика внизу.

Одновременно сейчас

5

Ручной MAX_CONCURRENT_SEARCHES=5 в .env. Fan-out и admission v2 на проде уже включены — потолок держит только эта цифра.

Одновременно физически

11–15

Книга весов памяти (2800 МБ): 11 «дорогих» dongchedi … ~15 на реальном миксе … 35 лёгких РФ-поисков.

Комфортный поток

~150 /час

Ожидание в очереди ≈ ноль, поиск целиком — 0,5–4 минуты. Сегодняшний пик — 8/час.

Жёсткий потолок

~240 /час

Дальше очередь растёт быстрее обработки. Ограничитель — 24 слота воркера деталей, не CPU и не БД.

Залп 30 человек / 5 мин

≤5 мин

Все 30 получают полный поиск максимум за 5 минут; при снятом ручном потолке ожидание в очереди — ноль.

Первым сгорит

прокси

4 адреса dongchedi, 4 encar, 1 mobile.de, 4 VPN-устройства avito, che168 — вообще с IP сервера.

Главная находка ревизии конфига: эпик Э2 (fan-out) на проде фактически уже включён — ADMISSION_CONTROL=v2, DETAIL_DISPATCH_MODE=fanout, GLOBAL_DETAIL_POOL=on, RISK_MODE=on, 24 воркера деталей. Спецификация очереди III писалась от дефолтов кода и считала его невключённым. Значит «включение fan-out» уже позади, и до реальных потолков остаётся один шаг: поднять ручную пятёрку (план Т2.2: 5 → 8 → 12 с наблюдением).

01 · Механика

Из чего сделан один поиск

Три последовательных ресурса; у каждого своя пропускная способность. Очередь пользователей стоит перед первым.

СтупеньРесурсПараллелизмВремя
Допуск (admission v2)книга весов памяти 2800 МБ + живой guard MemAvailable−250 МБ + ручной потолок5 (env) / 11–35 (вес)мгновенно или FIFO-очередь
Листинг (скан выдачи площадки)очередь listing, 3 слота (браузер ~200–400 МБ)3~5–15 с
Детали (карточка за карточкой)24 воркера detail_fetch, общий пул, анти-бан-капы площадок24 глобально6–25 с/машина

Медианы деталей из Loki за 48 ч: dongchedi 7,4 с · che168 6,1 с · encar 17,5 с. Медианные сессии (история 60 дней): dongchedi 29 с / 42 машины · che168 51 с / 29 · encar 12 с / 49. Хвосты честно длинные: p95 сессии dongchedi — 37 минут (большие выдачи).

ПлощадкаВес, МБАнти-бан-кап деталейЧем обеспеченПотолок площадки, сессий/час
DongCheDi250124 прокси × 3 фетча~140
Che1681204IP сервера (DIRECT, прокси нет)~80
Encar12016 (risk: до памяти)4 прокси — 4–6 параллельных на адрес~65
Avito80= пулу VPN4 residential-устройства (живой опрос)~19
mobile.de25041 прокси~23
Drom / Auto.ru80— (до 24)прямой HTTP, дёшевосотни

«Потолок площадки» = кап ÷ время детали × 3600 ÷ машин на сессию — сколько сессий площадка переварит за час, если жать её одну. Сумма капов (43+) больше 24 воркеров — при смешанной нагрузке первым упирается общий пул.

02 · Очередь

Сколько люди стоят в очереди

Дискретная симуляция: пуассоновский приход, реальный микс площадок (история), admission по книге весов, 3 листинг-слота, 24 слота деталей с капами, round-robin общего пула. Ожидание = от нажатия «Найти» до старта поиска.

Сегодняшний конфиг (ручной потолок 5)

Поисков/часОжидание p50Ожидание p95Вердикт
до 900 с1 сникто не ждёт
1201 с29 спочти никто
1501 с63 схвост начинает ждать
18018 с2,9 миночередь ощутима
210+3 мин14 минколлапс: хвост копится

После снятия ручного потолка (допуск по памяти)

Поисков/часОжидание p50Ожидание p95Поиск целиком p95Вердикт
до 1800 с1 с3,9 минникто не ждёт
2101 с53 с5,9 минтерпимо
24063 с5,4 мин10,7 минколено: 24 слота деталей
270+9,5 мин24 мин28 минколлапс

Спецсценарии: залп 30 человек за 5 минут — при потолке 5 ожидание p50 55 с, максимум 4 минуты, все дожидаются; со снятым потолком ожидания нет вовсе (максимум готовности — 5,2 мин). Волна из 20 поисков DongCheDi за 10 минут — книга весов пускает 11 одновременно, худший ждёт 109 с, все 20 готовы за ~5 минут.

Честные оговорки модели: она считает от медиан — реальные p95-хвосты (сессия dongchedi до 37 минут) при потолке 5 могут удерживать слот на десятки минут, так что нынешний конфиг хрупче модели именно на хвостах; продвижение очереди помимо хуков подстраховано свипом раз в 2 минуты (до +2 мин к ожиданию в редких гонках); переполнение очереди отдаёт отказ при 30 ждущих (и максимум 6 на пользователя — защита от абьюза).

03 · Где горит

Сайты и прокси: пороги возгорания

Настоящий внешний ограничитель — антибот площадок. Защита-предохранитель: 8 ошибок за 120 секунд по площадке → пауза диспатча этой площадки на 30 минут ДЛЯ ВСЕХ пользователей.

Г1

Che168 живёт с IP самого сервера

единая точка отказа

Прокси для che168 — ноль: DIRECT-режим. Живой замер 2026-06-26: 24 одновременных запроса с одного IP → API мгновенно отдаёт мусор и сажает адрес в пенальти (после буреста даже 4 потока валятся). Кап 4 — не перестраховка, а измеренная граница. Если IP сервера попадает в пенальти — che168 гаснет для всех разом, и это тот же IP, с которого ходит всё остальное DIRECT.

Г2

Пулы прокси — считаные штуки

линейный ограничитель

DongCheDi: 4 прокси (кап 12 = 4×3); потеря одного адреса = −25% ёмкости площадки. Encar: 4 прокси, а risk-режим разрешает до ~22 параллельных деталей — по 5–6 на адрес; предохранитель это переживёт, но баны адресов при устойчивой волне — вопрос времени. Mobile.de: один прокси. Avito: 4 residential-устройства (DataDome; жадность ловится мгновенно), потолок ~19 сессий/час. Хорошая новость: прокси — самый дешёвый и самый линейный апгрейд ёмкости из всех возможных.

Г3

Каскад предохранителя

30 минут тишины

Волна поисков одной площадки → рост ошибок → 8 за 2 минуты → площадка на паузе полчаса у всех (авто-восстановление по TTL). Для пользователя это выглядит как «поиск нашёл меньше обычного» или зависшие карточки. Это осознанная защита (лучше пауза, чем бан адресов), но при снятии ручного потолка частота таких пауз — главное, за чем смотреть в канарейке Т2.2.

04 · Все сценарии

Карта отказов — от вероятного до параноидального

Что ещё может сломаться, при каких условиях, как проявится и что его сдерживает.

СценарийПорог/условиеСимптомСдерживает
Диск: фото-кэшсвежая сессия ≈ 48 МБ фото; свободно 34 ГБ, GC хранит 7–30 днейпри сотнях «свежих» сессий/день диск кончается за дни; устойчиво без апгрейда ≈ 100–200 свежих сессий/день (повторы машин фото не перекачивают)GC ежедневно; решение — S3-миграция фото (план уже есть) или диск ≥120 ГБ (Э4)
Память / OOMкампания + пики поиска + сосед horeca (~450 МБ неучтённых)guard MemAvailable−250 придерживает новые поиски → очередь растёт при формально свободных слотах; глубже — swap-трэш на HDDguard + max-memory-per-child 150 МБ + jemalloc; после выноса horeca (Э5) бюджет честный
HDD под двойной нагрузкойпоиски (запись фото+БД) поверх кампаниислучайные чтения PG дорожают, всё вязнет по 3 мс/чтениестраничный кэш; лечится только SSD (Э4)
Оркестрация: 2 слота controlочередь default,parsing и переводы на одном воркере ×2задержка старта листингов при шторме коротких задачзадачи короткие; дренаж проекций ограничен бюджетом 45 с
Переводы/LLM-бюджетволна НОВЫХ китайских машин → батчи конфигов в OpenRouterрост очереди переводов (конфиги доезжают позже), расход кредитов пропорционален новым машинамглобальный RPM-лимитер + словарный кэш + Google-фолбэк; write-back «перевёл раз — сохрани»
VPN-оркестратор недоступенвнешний сервис пула устройствAvito гаснет (только он); кэш последнего размера пула смягчает морганияизоляция по площадке; предохранитель
Redis падаетединственный инстанс, 29 МБ, без maxmemoryживые сессии теряются; при рестарте воркеров зависшие помечаются отменёнными; поиск недоступен до подъёмаrestart unless-stopped; сессии по TTL; чистка на старте
Postgres соединенияmax_connections 400; сейчас ~30; худший теоретический ~150—запас ×2,5 даже в худшем случае
Абьюз очередилимиты: очередь 30, максимум 6 на пользователя5–6 злоумышленников с ботами забивают очередь → отказы новымлимиты есть; при росте аудитории снизить per-user до 2–3
DDoS на поискэндпоинт требует JWT; nginx 10 r/s на IPгостевым флудом не пробивается; ботнет с аккаунтами упрётся в очередь-30nginx + JWT + лимиты очереди
Один сервер на всёлюбой отказ железа/хостеравсё разом: сайт, поиск, БД, фототолько бэкапы; горизонт — второй сервер (вопрос B и дальше)
«Все площадки банят разом»болезнь прокси-провайдера / гео-блок РФ-адресовживой поиск деградирует до «Из БД» (склад работает, свежие — нет)предохранители по площадкам; склад из 480 К машин остаётся
05 · Рост

Лестница апгрейдов ёмкости

В порядке «дешевле и раньше — вперёд». Каждая ступень умножает конкретный ограничитель.

  1. Поднять ручной потолок 5 → 8 → 12 (план Т2.2, наблюдая частоту срабатываний предохранителя). Бесплатно: fan-out уже в проде. Эффект: залпы перестают ждать вовсе.
  2. Расширить пулы прокси — самый линейный рычаг: +4 прокси dongchedi = кап 12→24 (потолок площадки ×2); прокси для che168 = снять SPOF серверного IP; +1–2 mobile.de; устройства avito по потребности.
  3. SSD + RAM (Э4): книга весов растёт с памятью (16 ГБ ≈ ×2,5 одновременных), HDD-штраф исчезает, фото-стор перестаёт давить диск.
  4. Детальные воркеры 24 → 32–48 (после RAM): двигает жёсткий потолок 240/час к 350–500/час — до упора в капы площадок, поэтому вместе с п.2.
  5. Фото в S3 (план готов): снимает дисковый предел «свежих» сессий целиком.
  6. Второй сервер: убирает единую точку отказа; воркеры деталей выносимы первыми (чистые сетевые задачи).
Порядок наблюдения при подъёме потолка: частота пауз предохранителя по площадкам · MemAvailable в пиках · глубина очереди v2 · «время до первой карточки» (запрос из отчёта Н-09) · диск (фото-стор). Любая из метрик краснеет — ступень назад.