fix(wikipedia): позиция — байтовое смещение, а не номер статьи
All checks were successful
Deploy / test (push) Successful in 3m8s
Deploy / deploy (push) Successful in 30s

Заливка Википедии останавливалась сама собой: позиция хранилась как номер
статьи, и каждый прогон перечитывал дамп с начала. На 20 тысячах это стоило
6 минут из 25 доступных, на 27 тысячах — уже около десяти, а на сотне тысяч
съело бы весь бюджет и заливка встала бы совсем. Ровно это и наблюдалось:
прогон висел с нулём полученных статей, воркер на 100% CPU.

Переход на multistream-вариант дампа: он состоит из независимых bz2-блоков по
~95 статей, к нему прилагается индекс со смещениями. Позиция продолжения стала
байтовым смещением, прогон стартует мгновенно с нужного места.

Проверено на реальных файлах, а не по предположению: формат индекса
(offset:page_id:title), 21 уникальное смещение на 2001 статью, прыжок seek на
смещение из середины файла даёт валидный XML со страницами.

wikipedia_resume_offset.py — разовый пересчёт позиции при переходе: находит по
индексу блок с максимальным залитым page_id (получилось 273 281 821).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-09-05 23:26:16 +05:00
parent d3106efeee
commit d86bb606c7
3 changed files with 132 additions and 31 deletions

View File

@@ -580,12 +580,14 @@ def _parser_for(source_type: str, cfg: dict[str, Any]) -> tuple[Any, dict[str, A
"year_to": cfg.get("year_to"),
}
elif source_type == "wikipedia_ru":
# Массовый источник: дамп читается с позиции прошлого прогона
# Массовый источник: позиция — байтовое смещение в multistream-дампе.
# Раньше хранился номер статьи, и каждый прогон перечитывал дамп с
# начала: на 20 тысячах это стоило 6 минут из 25, дальше росло линейно
from wikipedia_ru import WikipediaRuParser as P
kwargs = {
"limit": limit,
"dump_path": query or None, # query = путь к дампу, если задан
"skip": int(cfg.get("resume_token") or 0),
"start_offset": int(cfg.get("resume_token") or 0),
}
elif source_type == "pmc_bulk":
from pmc_bulk import PMCBulkParser as P
@@ -742,7 +744,7 @@ def _ingest_bulk(
# Позиция продолжения: у Википедии — номер статьи в дампе,
# у PMC — токен страницы бакета
resume_token = doc.get("dump_position") or doc.get("resume_token") or resume_token
resume_token = doc.get("dump_offset") or doc.get("resume_token") or resume_token
batch.append(doc)
prog.count_fetched(prog.fetched + 1)