Конвейер etl_pipeline: сцепка дагов и пути запуска #156
Notifications
Due Date
No due date set.
Blocks
Depends on
#158 Звено DQ конвейера и dm.dq_summary
ddmitry/clickstream-data-platform
#154 Витрины стенда: даг dm_transform, revenue_daily и daily_traffic
ddmitry/clickstream-data-platform
Reference: ddmitry/clickstream-data-platform#156
Reference in new issue
Block a user
Part of #6.
Цель
Дневной конвейер:
etl_pipelineдёргаетdds_transform→dm_transformс ожиданием, готовность источника — первым шагом, конвейер вписан в
жизненный цикл мира. Учебный результат (etl.md): один и тот же запуск
одинаково верен из триггера, с кнопки менти и после падения.
Что войдёт
etl_pipeline: последовательный триггер слойных дагов с ожиданиемкаждого (ADR 0003 — зелёный конец графа не переживает отказ выше); без
расписания и параметров.
dds_transform— ожидание дожёванного хвостаhits:нулевое отставание потребителей по
system.kafka_consumers, опрос стаймаутом (etl.md, «Готовность источника»). Таблица эта локальна, а
топик читают обе ноды — отставание проверять по обеим
(
clusterAllReplicas), не только по ноде подключения.world_live_dayдёргает конвейер с ожиданиемпоследним шагом, после установки позиции;
world_initialize—последним шагом,
make upотдаёт собранные слои;world_next_dayконвейер не дёргает. Отказ конвейера на инициализации чинится тем же
путём, что и в живом дне, — ручным перезапуском
etl_pipeline: позицияуже стоит, повторный
world_initializeне нужен; назвать это в докетой же правкой.
world_initializeиworld_live_day— спеку жизненногоцикла (docs/specs/2026-08-21-world-lifecycle.md) и задетые доки
обновить тем же PR.
(правило спеки §11), решение зафиксировать комментарием.
Границы
мира и
logical_date— #111.запуска.
Кому что
Каркас дагов — Opus. Codex — прогоны трёх путей запуска и разбор логов по
брифу.
Сначала прочитать
триггер.
Проверка
make lint; на стендеmake smoke,make check-clickhouseиmake check-services(родился даг) зелёные.make rebuild-storage+ подъём:world_initializeзелёный, слоиDDS и витрины
revenue_daily/daily_trafficнаполнены без единогоручного шага.
world_live_dayзелёный целиком; после него всессиях — новый день, окно заказов пересобрано, витрины свежие.
world_next_day, затем один ручной запускetl_pipelineдогоняет всё (сессии — хвост, заказы — окно, карта иdaily_traffic— целиком).etl_pipelineиworld_live_day; повторный ручной запускetl_pipelineчинит безпараметров и памяти о прошлом прогоне.
опрос → 0 → трансформации.
Уточнение постановки после проверки живого стенда и развилки источника готовности.
Готовность
hitssystem.kafka_consumersв ClickHouse 26.3 показывает назначение разделов и текущий offset, но не конечный offset топика и не отставание.assignments.intent_sizeимеет другой смысл и на стенде равенNULL,rdkafka_statпуст даже у активных потребителей. Поэтому нулевое отставание через эту таблицу доказать нельзя.Готовность проверяется двумя последовательными барьерами внутри первого шага
dds_transform.confluent-kafkaшаг читает для группыclickstream_hitsтекущий и конечный offsets обоих разделов топикаhits. Барьер пройден, когда группа и оба раздела присутствуют, оба offsets известны, суммарное отставание равно нулю. Отсутствие группы, раздела или значения означает «ещё не готово», а не ноль.Distributed, но не его доставку на шард: этот размен принят вdocs/architecture/storage.md, раздел «Приём». Поэтому после нулевого отставания шаг черезclusterAllReplicasждёт, пока вsystem.distribution_queueне останется файлов дляods.event_distни на одной ноде. Остальные распределённые таблицы ждать не нужно: источником DDS служитods.event_v, а сырьё и таблицу ошибок трансформации не читают.Обе проверки опрашиваются раз в 3 с и делят один предел ожидания 300 с, а не получают по 300 с каждая. Каждый опрос пишет в журнал offsets и отставание по разделам, затем число файлов очереди по нодам. При отказе сообщение показывает последние offsets и незакрытые файлы с именами нод и
last_exception.Собственного состояния между опросами нет: offsets хранит Kafka, текущую очередь — ClickHouse, после перезапуска шаг вычисляет готовность заново. История
> 0 → 0остаётся только в журнале Airflow. Этого достаточно, потому что штатный генератор заканчивает запись до запуска ETL; параллельный посторонний производитель в контракт стенда не входит.clusterAllReplicas(system.kafka_consumers)из условия готовности уходит: Kafka отвечает сразу за всю группу и все разделы.clusterAllReplicasприменяется там, где у каждой ноды своя правда, — к очереди доставки ClickHouse.Отклонено: брать готовую метрику у Kafka exporter — рабочий конвейер стал бы зависеть от мониторинга; выводить готовность по строкам ODS — потребовался бы ожидаемый объём каждого прогона и связь ETL с генератором; включать и разбирать статистику librdkafka через ClickHouse — косвенный источник и лишнее изменение DDL ради вопроса, которым владеет Kafka.
Проверка
К списку команд добавить
make config-test: это дешёвая обязательная проверка правок DAG. Искусственный отказ не получает постоянного выключателя в коде: на приёмке временно ломается SQLdaily_traffic, после красногоworld_live_dayтестовая поломка убирается и ручнойetl_pipelineдолжен починить слои без параметров.Отдельный ADR не нужен. Исправление раздела «Готовность источника» в
docs/architecture/etl.mdвходит в PR задачи.