Merge pull request 'Дневной конвейер трансформаций: etl_pipeline рождается этапом 4' (#146) from 134-etl-pipeline into main
This commit was merged in pull request #146.
This commit is contained in:
commit
70270c2d54
6 files changed
+118
-10
No files matched your search
@@ -141,7 +141,10 @@
|
|||||||
|
|
||||||
Этап 3 забирает у этапа 5 первый настоящий даг. Раздел 9 мастер-спеки отдавал
|
Этап 3 забирает у этапа 5 первый настоящий даг. Раздел 9 мастер-спеки отдавал
|
||||||
даги этапу 5 целиком; приём заказов без дага не существует, поэтому порядок
|
даги этапу 5 целиком; приём заказов без дага не существует, поэтому порядок
|
||||||
меняется. `etl_pipeline` остаётся за этапом 5.
|
меняется. `etl_pipeline` остаётся за этапом 5. Позднее сдвинулся и он:
|
||||||
|
резолюция #134 родила его этапом 4 — [дневным конвейером
|
||||||
|
трансформаций](../architecture/etl.md), — а этапу 5 оставила партиционную
|
||||||
|
переобработку.
|
||||||
|
|
||||||
Расхождения с мастер-спекой, внесённые тем же коммитом: раздел 6 (чтец заказов
|
Расхождения с мастер-спекой, внесённые тем же коммитом: раздел 6 (чтец заказов
|
||||||
живёт на одной ноде и без матвью), раздел 7 (развилка закрыта, у `orders` одна
|
живёт на одной ноде и без матвью), раздел 7 (развилка закрыта, у `orders` одна
|
||||||
|
|||||||
@@ -135,7 +135,10 @@
|
|||||||
Этапы 3 и 5 зовут генератор тем же приёмом: пакетный забор слепка заказов
|
Этапы 3 и 5 зовут генератор тем же приёмом: пакетный забор слепка заказов
|
||||||
([ADR 0008](0008-order-ingestion.md)) прирастает к тому же работнику, а
|
([ADR 0008](0008-order-ingestion.md)) прирастает к тому же работнику, а
|
||||||
`etl_pipeline` этапа 5 получает готовую обвязку `DockerOperator` и готовое
|
`etl_pipeline` этапа 5 получает готовую обвязку `DockerOperator` и готовое
|
||||||
правило позиции.
|
правило позиции. Позднее резолюция #134 родила `etl_pipeline` этапом 4 —
|
||||||
|
[дневным конвейером трансформаций](../architecture/etl.md) без генераторных
|
||||||
|
шагов: обвязка и правило позиции остаются работникам, а живой день дёргает
|
||||||
|
конвейер после установки позиции.
|
||||||
|
|
||||||
Расхождения, внесённые тем же коммитом: раздел 8 спеки генератора (позицию
|
Расхождения, внесённые тем же коммитом: раздел 8 спеки генератора (позицию
|
||||||
двигал «только даг `next_day`»; теперь — всякий, кто сыграл день, значением
|
двигал «только даг `next_day`»; теперь — всякий, кто сыграл день, значением
|
||||||
|
|||||||
@@ -51,11 +51,11 @@
|
|||||||
- Служебные колонки — координаты собственной загрузки слоя; чужие ярлыки не
|
- Служебные колонки — координаты собственной загрузки слоя; чужие ярлыки не
|
||||||
переносятся, а спрашиваются у их слоя по ключу сущности. Вывод правила и
|
переносятся, а спрашиваются у их слоя по ключу сущности. Вывод правила и
|
||||||
цепочка расследования — [модель заказа](order.md).
|
цепочка расследования — [модель заказа](order.md).
|
||||||
|
- Наполняет слой [дневной конвейер](../etl.md): запуск, объём прогона и
|
||||||
|
замена партиций на кластере — его устройство.
|
||||||
|
|
||||||
## Открытые решения
|
## Открытые решения
|
||||||
|
|
||||||
- Запуск трансформаций и механика замены партиций на кластере — #134 и
|
|
||||||
этап 5.
|
|
||||||
- Витрины DM — #135.
|
- Витрины DM — #135.
|
||||||
|
|
||||||
## Родословная
|
## Родословная
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ ODS: это единственный устойчивый ключ сущнос
|
|||||||
объектов».
|
объектов».
|
||||||
|
|
||||||
Механика запуска — где собирается партиция и как подменяется на кластере —
|
Механика запуска — где собирается партиция и как подменяется на кластере —
|
||||||
сюда не входит: это устройство трансформаций (#134, этап 5).
|
сюда не входит: это устройство [дневного конвейера](../etl.md).
|
||||||
|
|
||||||
## Служебные колонки
|
## Служебные колонки
|
||||||
|
|
||||||
@@ -95,8 +95,8 @@ ODS: это единственный устойчивый ключ сущнос
|
|||||||
|
|
||||||
## Не входит
|
## Не входит
|
||||||
|
|
||||||
- Механика запуска трансформации и замены партиций на кластере — #134 и
|
- Механика запуска трансформации и замены партиций на кластере —
|
||||||
этап 5.
|
[дневной конвейер](../etl.md).
|
||||||
- Контур проверок качества (даг DQ, `dm.dq_summary`) — отдельный разговор
|
- Контур проверок качества (даг DQ, `dm.dq_summary`) — отдельный разговор
|
||||||
этапа 4.
|
этапа 4.
|
||||||
- Инкрементальное наполнение вместо пересборки — техдолг #2.
|
- Инкрементальное наполнение вместо пересборки — техдолг #2.
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
Источник сборки — `dds.event_v` ([контракт события](event.md)): сессии
|
Источник сборки — `dds.event_v` ([контракт события](event.md)): сессии
|
||||||
нужны от него ключи нарезки, тип события, страница, UTM и паспорт куки.
|
нужны от него ключи нарезки, тип события, страница, UTM и паспорт куки.
|
||||||
Механика запуска — где собирается партиция и как подменяется на кластере —
|
Механика запуска — где собирается партиция и как подменяется на кластере —
|
||||||
не входит: это устройство трансформаций (#134, этап 5).
|
не входит: это устройство [дневного конвейера](../etl.md).
|
||||||
|
|
||||||
## Сверка с эталоном
|
## Сверка с эталоном
|
||||||
|
|
||||||
@@ -115,8 +115,8 @@
|
|||||||
|
|
||||||
## Не входит
|
## Не входит
|
||||||
|
|
||||||
- Механика запуска трансформации и замены партиций на кластере — #134 и
|
- Механика запуска трансформации и замены партиций на кластере —
|
||||||
этап 5.
|
[дневной конвейер](../etl.md).
|
||||||
- Контур проверок качества (даг DQ, `dm.dq_summary`) — отдельный разговор
|
- Контур проверок качества (даг DQ, `dm.dq_summary`) — отдельный разговор
|
||||||
этапа 4.
|
этапа 4.
|
||||||
- Форма витрин над сессиями — #135.
|
- Форма витрин над сессиями — #135.
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# Дневной конвейер трансформаций
|
||||||
|
|
||||||
|
Как принятые источники превращаются в модель DDS и витрины DM: кто запускает
|
||||||
|
трансформации, когда и в каком объёме. Правила самих сущностей — зерно,
|
||||||
|
движки, что именно пересобирается — живут в доках слоя
|
||||||
|
([карта модели DDS](dds/README.md)); здесь — только конвейер.
|
||||||
|
|
||||||
|
Спека обещала `etl_pipeline` этапом 5 — он понадобился раньше. Конвейер
|
||||||
|
рождается этапом 4, и временного в нём ничего нет: дневная сборка вперёд
|
||||||
|
останется и после. Этапу 5 достаётся его законный предмет — партиционная
|
||||||
|
переобработка, умение переиграть произвольный прошлый день по команде.
|
||||||
|
|
||||||
|
## Форма
|
||||||
|
|
||||||
|
Дневной конвейер на стенде один — даг `etl_pipeline`. Своей работы
|
||||||
|
у него нет: он дёргает слойные даги последовательно и ждёт каждый —
|
||||||
|
`dds_transform`, затем `dm_transform`. Контур DQ этапа 4 встанет его же
|
||||||
|
звеном после DM; состав звена — предмет развилки витрин (#135) и нарезки.
|
||||||
|
|
||||||
|
Слойные даги устроены по образцу `orders_ingest`: без расписания, один
|
||||||
|
активный прогон, запускаются триггером конвейера или рукой при разборе
|
||||||
|
происшествий. Витрины внутри `dm_transform` — отдельные задачи.
|
||||||
|
|
||||||
|
## Три пути запуска
|
||||||
|
|
||||||
|
- **Живой день.** `world_live_day` дёргает конвейер с ожиданием — последним
|
||||||
|
шагом, после установки позиции. Порядок несёт смысл: день сыгран — факт,
|
||||||
|
упавшая трансформация его не отменяет, поэтому позиция ставится раньше; но
|
||||||
|
зеленеть, не узнав, разложился ли день, работник не должен
|
||||||
|
([ADR 0003](../adr/0003-dag-run-state.md)).
|
||||||
|
Такой отказ чинится перезапуском `etl_pipeline` рукой — перезапуску ничего
|
||||||
|
не нужно помнить, см. «Объём прогона».
|
||||||
|
- **Разгон пачкой.** `world_next_day` конвейер не дёргает: пульт управляет
|
||||||
|
генератором и только им. После разгона менти запускает конвейер сам —
|
||||||
|
и видит, как слои догоняют уехавший вперёд мир.
|
||||||
|
- **Рождение мира.** `world_initialize` дёргает конвейер последним шагом:
|
||||||
|
`make up` отдаёт стенд с собранными слоями, а не пустые витрины. Уроки
|
||||||
|
ручного запуска начинаются со следующих дней.
|
||||||
|
|
||||||
|
## Объём прогона
|
||||||
|
|
||||||
|
Параметров у конвейера нет: объём он выводит сам из `world_position` и
|
||||||
|
состояния слоёв. Сессии догоняют хвост — от последнего собранного дня до
|
||||||
|
последнего прожитого; заказы пересобирают дышащее окно K от позиции; карта
|
||||||
|
идентичностей пересчитывается целиком; правила витрин — у витрин (#135).
|
||||||
|
Поэтому один и тот же запуск одинаково верен из триггера, с кнопки менти и
|
||||||
|
после падения, а разгону на семь дней хватает одного прогона.
|
||||||
|
|
||||||
|
## Готовность источника
|
||||||
|
|
||||||
|
Первый шаг `dds_transform` — дождаться, пока хвост топика `hits` дожёван:
|
||||||
|
отставание его потребителей нулевое (`system.kafka_consumers`). Зелёный
|
||||||
|
приём заказов о событиях не говорит ничего — топики разные и потребители
|
||||||
|
разные. В живом режиме зазор ничтожен, но в пакетном генератор выстреливает
|
||||||
|
дни в топик быстрее, чем чтец их прожёвывает, и сессии собрались бы по
|
||||||
|
недожёванному дню. DQ-сверка такой день подсветит, но починить его до
|
||||||
|
этапа 5 нечем: профилактика дешевле ремонта, которого ещё нет.
|
||||||
|
|
||||||
|
## Идемпотентность
|
||||||
|
|
||||||
|
Партиция не заменяется простой вставкой. День собирается в таблицу-двойник —
|
||||||
|
вставка через Distributed раскладывает строки по шардам, — затем
|
||||||
|
`REPLACE PARTITION` на кластере атомарно подменяет кусок каждого шарда. Эта
|
||||||
|
механика — часть самих трансформаций и строится этапом 4: без неё дневной
|
||||||
|
прогон не повторяем.
|
||||||
|
|
||||||
|
## Не входит
|
||||||
|
|
||||||
|
- Партиционная переобработка — переиграть произвольный прошлый день или
|
||||||
|
диапазон, включая форму необязательных параметров того же дага, — этап 5
|
||||||
|
(#7); туда же стык #111 про дату модельного мира и `logical_date`.
|
||||||
|
- Инкрементальный ETL вместо пересборки — техдолг #2.
|
||||||
|
- Состав витрин `dm_transform` и звена DQ — #135 и нарезка этапа 4.
|
||||||
|
|
||||||
|
## Отклонённые варианты
|
||||||
|
|
||||||
|
- **Задачи трансформаций прямо в работниках пульта.** Один зелёный прогон —
|
||||||
|
весь день, но пульт — про ось времени: работников два, шаги дублировались
|
||||||
|
бы, а этапу 5 пришлось бы выдирать их обратно.
|
||||||
|
- **Make-цель или SQL рукой при приёмке.** Второй оркестратор рядом с
|
||||||
|
Airflow — против [ADR 0013](../adr/0013-world-lifecycle.md), — а в живом
|
||||||
|
режиме слои копили бы отставание молча.
|
||||||
|
- **Временный даг с нейтральным именем до этапа 5.** Дневная сборка вперёд
|
||||||
|
никуда не денется, переезд был бы переименованием ради выдуманной границы.
|
||||||
|
- **Диапазон дней параметрами триггера.** Ручному запуску менти параметры
|
||||||
|
передавать некому, а перезапуск после падения требовал бы помнить conf
|
||||||
|
упавшего прогона.
|
||||||
|
- **Принять гонку с хвостом `hits`.** Дыра всплыла бы в DQ-сверке, а
|
||||||
|
чиниться — не раньше этапа 5.
|
||||||
|
|
||||||
|
## Связанные решения
|
||||||
|
|
||||||
|
- [ADR 0003](../adr/0003-dag-run-state.md) — зелёный конец графа не
|
||||||
|
переживает отказ выше: отсюда ожидания в триггерах.
|
||||||
|
- [ADR 0009](../adr/0009-world-control.md) — пульт мира: его работник
|
||||||
|
живого дня и дёргает конвейер.
|
||||||
|
- [ADR 0013](../adr/0013-world-lifecycle.md) — жизненный цикл мира: почему
|
||||||
|
прикладным процессом владеет Airflow и почему `world_initialize` кончается
|
||||||
|
собранными слоями.
|
||||||
|
- Резолюция — тикет #134 карты #127; что пересобирает каждая сущность —
|
||||||
|
[заказ](dds/order.md), [сессия](dds/session.md),
|
||||||
|
[карта идентичностей](dds/identity.md).
|
||||||
Reference in new issue
Block a user