feat(airflow): пульт стал world_init, добавлен DAG world_next_day (#4)
- Зачем:
- список DAG'ов должен читаться лесенкой ddl_init → world_init →
world_next_day, а путь менти — проходиться пустыми формами
(issue #4, спека редизайна пути менти, решения 2–3).
- Что:
- generator_control переименован в world_init, дефолт операции —
import; next-day ушёл из выпадашки в отдельный DAG;
- новый беспараметрный world_next_day: расписание */30 * * * *,
создаётся на паузе, catchup=False, max_active_runs=1; общие
задачи вынесены в airflow/dags/utils/startup_history_tasks.py;
- доки и контрактные тесты обновлены синхронно; быстрый старт
README — без make ddl, схему создаёт DAG ddl_init.
- Проверка:
- make test (210 + 31) и make lint зелёные;
- живая приёмка на чистом стенде: world_init пустой формой
импортировал эталонный мир за 217 с (3 дня, 280 437 событий),
world_next_day после снятия с паузы добавляет ровно один день
за прогон, дашборд Superset собирается.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+29
-25
@@ -48,45 +48,48 @@ volumes или live-генератором. Для стыка backfill/live от
|
||||
|
||||
## Airflow DAGs
|
||||
|
||||
Штатный ручной путь начинается с `generator_control`: чистый стенд получает
|
||||
стартовую историю генератора, затем этот же DAG запускает ETL и проверку.
|
||||
Штатный ручной путь начинается с `world_init`: пустая форма импортирует
|
||||
эталонный мир, затем этот же DAG запускает ETL и проверку.
|
||||
`kafka_load` остаётся для экспериментов и совместимости учебного стенда.
|
||||
|
||||
### `generator_control`
|
||||
### `world_init`
|
||||
|
||||
- Запуск: ручной (`Trigger DAG`).
|
||||
- Назначение: пульт стартовой истории генератора.
|
||||
- Назначение: импорт или служебная сборка стартового мира.
|
||||
- Операции:
|
||||
- `import` — операция по умолчанию: импортировать портативный артефакт, затем
|
||||
запустить `etl_pipeline` и дождаться `success`;
|
||||
- `backfill` — создать стартовую историю, затем запустить `etl_pipeline` и
|
||||
дождаться `success`;
|
||||
- `import` — импортировать портативный артефакт, затем запустить
|
||||
`etl_pipeline` и дождаться `success`;
|
||||
- `next-day` — восстановить мир из state, добавить 24 модельных часа,
|
||||
затем запустить `etl_pipeline` и дождаться `success`;
|
||||
- `check` — сверить ClickHouse с manifest из Kafka.
|
||||
- Параметры:
|
||||
- `operation` (`backfill` / `import` / `next-day` / `check`);
|
||||
- `operation` (`import` / `backfill` / `check`);
|
||||
- `profile` — список берётся из `PROFILES` генератора;
|
||||
- `duration` — `6h`, `2d` и т.п.; пусто означает длительность профиля;
|
||||
- `seed`, `model_time_speed` — необязательные переопределения мира;
|
||||
- `artifact_path` — для `backfill` путь сохранения; для `import` путь чтения.
|
||||
При пустом поле импортируется эталонный мир из репозитория;
|
||||
- `expected_t_end` — необязательная ожидаемая граница перед `next-day`.
|
||||
При расхождении запуск показывает ожидаемое и фактическое значения.
|
||||
При пустом поле импортируется эталонный мир из репозитория.
|
||||
|
||||
Backfill/import требуют чистый стенд: пустые data-топики Kafka и пустые
|
||||
`stg.*_raw`. При отказе очистите стенд через `make clean`. Операции `continue`
|
||||
в DAG нет: live-генератор — долгоживущий сервис, его запускают с консоли через
|
||||
`make generator-continue`.
|
||||
|
||||
`next-day` работает на непустом стенде и не использует проверку чистоты.
|
||||
Перед записью пульт требует manifest, state ровно на его `T_end` и остановленный
|
||||
live-генератор. Настройки мира берутся из manifest; поля `profile`, `duration`,
|
||||
`seed` и `model_time_speed` формы для этой операции не применяются. Один запуск
|
||||
добавляет полуоткрытый диапазон `[T_end, T_end + 24h)` в UTC. Новая граница
|
||||
появляется в `boundaries`; старый manifest без поля читается как `[T0, T_end]`.
|
||||
Расписание остаётся выключенным (`schedule=None`), а `max_active_runs=1` не даёт
|
||||
двум доливкам выполняться параллельно.
|
||||
### `world_next_day`
|
||||
|
||||
- Запуск: вручную с пустой формой.
|
||||
- Параметров нет.
|
||||
- Один запуск восстанавливает мир из state, добавляет 24 модельных часа,
|
||||
запускает `etl_pipeline` с полной пересборкой и сверяет витрины с manifest.
|
||||
- Расписание задано каждые 30 минут, но DAG создаётся на паузе; `catchup=False`.
|
||||
Не включайте расписание до внедрения накопительных счётчиков manifest.
|
||||
- `max_active_runs=1` не даёт двум доливкам выполняться параллельно.
|
||||
|
||||
`world_next_day` работает на непустом стенде и не использует проверку чистоты.
|
||||
Перед записью он требует manifest, state ровно на его `T_end` и остановленный
|
||||
live-генератор. Настройки мира берутся из manifest. Один запуск добавляет
|
||||
полуоткрытый диапазон `[T_end, T_end + 24h)` в UTC. Новая граница появляется в
|
||||
`boundaries`; старый manifest без поля читается как `[T0, T_end]`.
|
||||
|
||||
После двух доливок проверьте завершённые стыки:
|
||||
|
||||
@@ -98,10 +101,11 @@ make generated-history-chain-check
|
||||
смену browser/referer/utm внутри переходящих визитов. Она не меняет
|
||||
`make generated-history-runtime-check` для стыка backfill/live.
|
||||
|
||||
Точка фиксации `next-day` — новый manifest. Порядок записи: data-топики, state,
|
||||
manifest. Автоматического отката нет. Если запуск упал до публикации manifest,
|
||||
Результат запуска `world_next_day` фиксируется новым manifest. Порядок записи:
|
||||
data-топики, state, manifest. Автоматического отката нет. Если запуск упал до
|
||||
публикации manifest,
|
||||
не повторяйте доливку поверх возможного хвоста. Очистите стенд и переимпортируйте
|
||||
последний исправный портативный артефакт, затем повторите `next-day`.
|
||||
последний исправный портативный артефакт, затем повторите запуск `world_next_day`.
|
||||
|
||||
Текущая версия пересчитывает накопительные счётчики и контрольные суммы по всей
|
||||
доступной истории data-топиков Kafka. Поэтому время выполнения и расход памяти
|
||||
@@ -689,8 +693,8 @@ make generated-history-runtime-check
|
||||
## Быстрые проверки
|
||||
|
||||
- Kafka ingest: наличие данных генератора в `stg.*` и типизированных строк в `ods.*`.
|
||||
- Airflow UI: `http://localhost:8080` показывает DAG `ddl_init`, `generator_control`,
|
||||
`kafka_load`, `etl_pipeline`; основной ручной пульт генератора — `generator_control`.
|
||||
- Airflow UI: `http://localhost:8080` показывает лестницу `ddl_init` →
|
||||
`world_init` → `world_next_day`, а также `kafka_load` и `etl_pipeline`.
|
||||
- BI: витрина `dm.v_events_enriched` отвечает за разумное время при фильтре по дате.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user