avito exhaustive: резюм пере-пробивает готовые полосы — на худом пуле весь бан-бюджет сгорает до первой новой корзины #3315

Closed
opened 2026-09-01 17:13:12 +00:00 by bot-backend · 0 comments
Collaborator

Замер 01.09.2026, прогон 5718. Источник avito_full_load_exhaustive без успешного завершения 71,9 дня, ежедневный freshness-алерт.

Хроника трёх прогонов одной цепочки

run когда итог чистый прогресс
5402 30.08 13:40 cancelled — деплой пересоздал scraper на 14-й минуте чекпоинт: 9 корзин студий
5679 01.09 07:20 banned за 1 секунду — пул пуст (#3310) 0
5718 01.09 16:44 banned на 21-й минуте — обе живые ноды получили бан-страницы 0 новых корзин

Суммарный прогресс за три прогона и три дня: ноль. Чекпоинт после 5718 байт-в-байт равен чекпоинту 5402.

Что делал 5718 свои 21 минуту

Резюм честно отработал (цепочка 5718←5679←5402, 9 корзин зачтены), но лог показывает работу внутри зачтённой территории:

avito: total=None for room_studii [4062500, 4124999] depth=4 — rotating IP + retry
avito: total=None for room_studii [4093750, 4124999] depth=5 — rotating IP + retry

room_studii:4000000:4999999 в done-леджере есть, а прогон дробит поддиапазоны внутри неё. Это не баг резюма, а его документированная семантика (serp.py:1199): «в exhaustive-режиме probe-запросы всё равно выполняются, skip проверяется уже в листе, после probe». Пропускается пагинация листа, но дерево деления пере-пробивается живыми запросами каждый раз.

Почему это стало проблемой именно сейчас

При здоровом пуле пере-пробинг — приемлемый оверхед. При пуле из 1-2 нод (#2638) он смертелен: бан-бюджет обеих нод сгорает на пробах уже готовых полос, и до первой НОВОЙ корзины прогон не доживает. Ротация работала как задумана — оттянула смерть с 1 секунды до 21 минуты — но все эти 21 минуту запросы жгли территорию, которая уже в чекпоинте.

Вторая грань той же проблемы: ключи чекпоинта — границы динамической бисекции. Рынок сдвинулся → totals другие → дерево делится иначе → новые листья (4062500:4124999) не равны старым (4000000:4999999) даже там, где диапазон полностью покрыт. Ключ, выведенный из изменчивых данных, нестабилен между прогонами — знакомый класс.

Предлагаемое лечение

Containment-проверка до пробы: перед пробингом полосы [lo,hi] для room_label — если диапазон целиком покрыт объединением done-диапазонов этой комнатности, пропустить без единого запроса. Парсинг ключей room:lo:hi в интервалы тривиален. Проба остаётся только для полос, где есть непокрытый остаток.

Оценка S-M (ядро бисекции, нужны тесты на покрытие интервалов). Приёмка: прогон-резюм на полностью готовой комнатности не делает по ней НИ ОДНОГО запроса (сейчас — десятки).

Честная оговорка

Даже с идеальным skip источник не завершится, пока пул не пополнен: новые корзины тоже требуют запросов, а обе ноды сейчас в бане (13 — до 04.09, 9 — до 03.09, 1 — до 30.09). Первичен #2638; эта правка делает так, чтобы каждая попытка тратила бан-бюджет на НОВУЮ работу, а не на повтор.

Окно расписания уже переведено на ночь (01–04 UTC) — субботние убийства деплоями (#3074) из хроники исчезают.

Refs: #2638 (пул — решение владельца), #3310 (пустой пул как отдельный класс), #3074 (деплой против длинных прогонов), #3288 (классификация отказов).

Замер 01.09.2026, прогон 5718. Источник `avito_full_load_exhaustive` без успешного завершения **71,9 дня**, ежедневный freshness-алерт. ## Хроника трёх прогонов одной цепочки | run | когда | итог | чистый прогресс | |---|---|---|---| | 5402 | 30.08 13:40 | cancelled — деплой пересоздал scraper на 14-й минуте | чекпоинт: 9 корзин студий | | 5679 | 01.09 07:20 | banned за **1 секунду** — пул пуст (#3310) | 0 | | 5718 | 01.09 16:44 | banned на 21-й минуте — обе живые ноды получили бан-страницы | **0 новых корзин** | Суммарный прогресс за три прогона и три дня: **ноль**. Чекпоинт после 5718 байт-в-байт равен чекпоинту 5402. ## Что делал 5718 свои 21 минуту Резюм честно отработал (цепочка 5718←5679←5402, 9 корзин зачтены), но лог показывает работу **внутри зачтённой территории**: ``` avito: total=None for room_studii [4062500, 4124999] depth=4 — rotating IP + retry avito: total=None for room_studii [4093750, 4124999] depth=5 — rotating IP + retry ``` `room_studii:4000000:4999999` в done-леджере есть, а прогон дробит поддиапазоны внутри неё. Это **не баг резюма, а его документированная семантика** (`serp.py:1199`): «в exhaustive-режиме probe-запросы всё равно выполняются, skip проверяется уже в листе, после probe». Пропускается пагинация листа, но дерево деления пере-пробивается живыми запросами каждый раз. ## Почему это стало проблемой именно сейчас При здоровом пуле пере-пробинг — приемлемый оверхед. При пуле из **1-2 нод** (#2638) он смертелен: бан-бюджет обеих нод сгорает на пробах уже готовых полос, и до первой НОВОЙ корзины прогон не доживает. Ротация работала как задумана — оттянула смерть с 1 секунды до 21 минуты — но все эти 21 минуту запросы жгли территорию, которая уже в чекпоинте. Вторая грань той же проблемы: ключи чекпоинта — границы динамической бисекции. Рынок сдвинулся → totals другие → дерево делится иначе → новые листья (`4062500:4124999`) не равны старым (`4000000:4999999`) даже там, где диапазон полностью покрыт. Ключ, выведенный из изменчивых данных, нестабилен между прогонами — знакомый класс. ## Предлагаемое лечение Containment-проверка **до пробы**: перед пробингом полосы `[lo,hi]` для room_label — если диапазон целиком покрыт объединением done-диапазонов этой комнатности, пропустить без единого запроса. Парсинг ключей `room:lo:hi` в интервалы тривиален. Проба остаётся только для полос, где есть непокрытый остаток. Оценка S-M (ядро бисекции, нужны тесты на покрытие интервалов). Приёмка: прогон-резюм на полностью готовой комнатности не делает по ней НИ ОДНОГО запроса (сейчас — десятки). ## Честная оговорка Даже с идеальным skip источник не завершится, пока пул не пополнен: новые корзины тоже требуют запросов, а обе ноды сейчас в бане (13 — до 04.09, 9 — до 03.09, 1 — до 30.09). Первичен #2638; эта правка делает так, чтобы каждая попытка тратила бан-бюджет на НОВУЮ работу, а не на повтор. Окно расписания уже переведено на ночь (01–04 UTC) — субботние убийства деплоями (#3074) из хроники исчезают. Refs: #2638 (пул — решение владельца), #3310 (пустой пул как отдельный класс), #3074 (деплой против длинных прогонов), #3288 (классификация отказов).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3315
No description provided.