docs(handbook): упрощен язык путеводителя по стенду
Зачем: помочь учащемуся понять путь данных и работу служб перед выполнением заданий. Что: вычитаны оглавление и пять глав, пояснены термины, убраны внутренние метафоры и повторы. Уточнены пояснения к SQL и показателям мониторинга. Проверка: 62 локальные ссылки и 6 входящих ссылок на разделы проверены; 8 блоков SQL и схем сохранены. git diff --cached --check прошел.
This commit is contained in:
1 parent
ce15836093
commit
915e976fc2
6 files changed
+225
-193
No files matched your search
@@ -1,7 +1,8 @@
|
||||
# Потоки Airflow и даги модельного времени
|
||||
|
||||
В Airflow два рода дагов. Даги мира создают мир и проигрывают модельные дни,
|
||||
а дневной конвейер раскладывает сыгранный день по слоям хранилища.
|
||||
Airflow управляет генерацией данных и их обработкой в хранилище. Это разные
|
||||
этапы: сначала в Kafka поступают события и заказы за день работы магазина,
|
||||
затем по ним рассчитываются данные DDS и витрины DM.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -14,64 +15,72 @@ flowchart LR
|
||||
|
||||
## Два потока входят по-разному
|
||||
|
||||
События приходят в топик `hits`. Хранилище разбирает их само и непрерывно:
|
||||
События поступают в топик `hits` и обрабатываются по мере поступления:
|
||||
материализованные представления переносят строки из STG в ODS без участия
|
||||
Airflow.
|
||||
|
||||
Заказы приходят в топик `orders` один раз в модельные сутки, целым слепком. У
|
||||
слепка есть начало и конец, поэтому даг `orders_ingest` забирает его одной
|
||||
порцией. Такой способ приема называется [пакетным](../../CONTEXT.md).
|
||||
Заказы поступают в топик `orders` раз в модельные сутки одной выгрузкой.
|
||||
Она содержит состояние заказов на конец дня и называется слепком.
|
||||
Даг `orders_ingest` загружает ее целиком. Такой способ приема называется
|
||||
[пакетным](../../CONTEXT.md).
|
||||
|
||||
## Даги мира
|
||||
|
||||
Два дага с тегом «жизненный цикл мира» отвечают за стартовый мир:
|
||||
В документации миром называется учебный магазин с его посетителями,
|
||||
товарами и заказами. Время в нем идет отдельно от календарного.
|
||||
Два дага с тегом «жизненный цикл мира» создают начальные данные:
|
||||
|
||||
| Даг | Что делает |
|
||||
|---|---|
|
||||
| `world_initialize` | Создает стартовый мир, если его еще нет |
|
||||
| `world_recreate` | Стирает данные мира и собирает стартовый мир заново |
|
||||
| `world_initialize` | Создает начальные данные, если их еще нет |
|
||||
| `world_recreate` | Удаляет прикладные данные и создает их заново |
|
||||
|
||||
Три дага с тегом «модельное время» проигрывают следующие дни. Именно их
|
||||
называют дагами модельного времени.
|
||||
Для добавления следующих дней есть три дага с тегом «модельное время»:
|
||||
|
||||
| Даг | Что делает |
|
||||
|---|---|
|
||||
| `world_next_day` | Играет следующие дни пачкой |
|
||||
| `world_live_day` | Играет следующий день в темпе модельного времени |
|
||||
| `world_live` | Запускает живые дни один за другим, пока снят с паузы |
|
||||
| `world_next_day` | Генерирует данные за следующие дни без пауз между событиями |
|
||||
| `world_live_day` | Генерирует данные за следующий день постепенно, примерно за 24 минуты |
|
||||
| `world_live` | Запускает `world_live_day` день за днем, пока снят с паузы |
|
||||
|
||||
Сколько дней уже сыграно, стенд помнит в переменной Airflow `world_position`:
|
||||
в ней лежит номер первого несыгранного дня. `world_next_day` и `world_live_day`
|
||||
записывают новое значение только после успешно сыгранного дня; оборванный
|
||||
прогон его не меняет.
|
||||
В переменной Airflow `world_position` хранится номер следующего дня для
|
||||
генерации. Например, при значении `8` генератор уже отправил события
|
||||
за дни с 0 по 7.
|
||||
|
||||
Сыграв день D, эти два дага отправляют слепок заказов за день D−1 и ждут, пока
|
||||
`orders_ingest` его примет. Эти связи разобраны в [справочнике
|
||||
мира](../architecture/world.md#даги-модельного-времени).
|
||||
`world_next_day` и `world_live_day` сначала отправляют события дня D,
|
||||
затем — слепок заказов за предыдущий день D−1. Они ждут, пока `orders_ingest`
|
||||
загрузит слепок, и только после успешного завершения дня обновляют
|
||||
`world_position`. Если генерация или прием данных завершились с ошибкой,
|
||||
номер дня остается прежним. Подробности — в [справочнике генератора
|
||||
и модельного времени](../architecture/world.md#даги-модельного-времени).
|
||||
|
||||
## Дневной конвейер
|
||||
|
||||
У `etl_pipeline` нет своей обработки. Он по очереди запускает `dds_transform`,
|
||||
`dm_transform` и `dq_check` и ждет каждый даг. Параметров у него нет: сколько
|
||||
дней обработать, он сам определяет по `world_position` и по тому, что уже лежит
|
||||
в слоях. Поэтому один и тот же запуск верен и когда его запустил другой даг, и
|
||||
когда вы нажали кнопку, и когда его повторяют после сбоя. Детали есть в
|
||||
Даг `etl_pipeline` по очереди запускает `dds_transform`, `dm_transform`
|
||||
и `dq_check`, дожидаясь завершения каждого. Они рассчитывают данные DDS,
|
||||
обновляют витрины DM и проверяют качество результата.
|
||||
|
||||
При запуске `etl_pipeline` не нужно указывать даты. Дни для обработки
|
||||
определяются по `world_position` и по уже загруженным данным в слоях.
|
||||
Детали есть в
|
||||
[справочнике конвейера](../architecture/etl.md#объём-прогона).
|
||||
|
||||
`world_next_day` не запускает конвейер. После него слои хранилища отстают от
|
||||
мира, пока вы не запустите конвейер сами. `world_live_day`, наоборот,
|
||||
запускает `etl_pipeline` и ждет его. Поэтому даг остается в работе и после
|
||||
конца модельного дня.
|
||||
После `world_next_day` новые события и заказы уже загружены, но данные DDS
|
||||
и DM еще не пересчитаны: запустите `etl_pipeline` вручную.
|
||||
`world_live_day` запускает его автоматически и ждет завершения. Поэтому
|
||||
`world_live_day` может продолжать работу после окончания генерации за день.
|
||||
|
||||
## Что значит красный
|
||||
## Если даг завершился с ошибкой
|
||||
|
||||
Красный `etl_pipeline` не отменяет сыгранного дня: `world_position` уже
|
||||
записана. Достаточно перезапустить конвейер рукой; разбираться, на чем
|
||||
остановился прошлый прогон, не нужно. Кто запускает конвейер, описано в
|
||||
Ошибка в `etl_pipeline` не меняет `world_position`: генерация и прием
|
||||
данных за день уже завершились. После устранения причины ошибки
|
||||
перезапустите конвейер вручную. Даты для повторной обработки он определит сам.
|
||||
Кто запускает конвейер, описано в
|
||||
[разделе о трех путях запуска](../architecture/etl.md#три-пути-запуска).
|
||||
|
||||
Качество данных проверяет контур DQ. В дневном конвейере это даг `dq_check`:
|
||||
упавшая задача печатает в лог ключи строк, не прошедших проверку. Состав
|
||||
За качество данных отвечают проверки DQ (Data Quality) в даге `dq_check`.
|
||||
Если проверка находит расхождение, задача завершается с ошибкой и записывает
|
||||
в журнал ключи строк, которые ее не прошли. Состав
|
||||
проверок описан в [разделе «Звено DQ
|
||||
конвейера»](../architecture/dm.md#звено-dq-конвейера).
|
||||
|
||||
@@ -87,8 +96,9 @@ Airflow.
|
||||
Откройте Airflow по адресу из раздела [«Адреса и
|
||||
пароли»](../../README.md#адреса-и-пароли). В Admin → Variables найдите
|
||||
`world_position`. Затем запустите `world_next_day` на один день по [инструкции
|
||||
из README](../../README.md#добавить-данные-за-следующие-дни). Убедитесь, что `orders_ingest`
|
||||
отработал, а витрины еще ничего не получили. Запустите `etl_pipeline` рукой.
|
||||
из README](../../README.md#добавить-данные-за-следующие-дни). Убедитесь, что
|
||||
`orders_ingest` завершился успешно, а в витринах нового дня еще нет.
|
||||
Запустите `etl_pipeline` вручную и дождитесь его завершения.
|
||||
|
||||
В DBeaver, подключенном по
|
||||
[инструкции](../../README.md#подключиться-из-dbeaver), выполните два запроса:
|
||||
@@ -106,9 +116,10 @@ ORDER BY report_date DESC
|
||||
LIMIT 3;
|
||||
```
|
||||
|
||||
В трафике уже есть сыгранный день, а в выручке только предыдущий: вместе с этим
|
||||
днем пришел слепок заказов за предыдущий. Выручка сыгранного дня появится после
|
||||
следующего.
|
||||
В витрине трафика уже есть новый день, а в выручке последняя дата —
|
||||
предыдущий день. Причина в выгрузке заказов: вместе с событиями дня D
|
||||
приходит слепок за день D−1. Выручка дня D появится после генерации
|
||||
дня D+1 и запуска конвейера.
|
||||
|
||||
## Куда дальше
|
||||
|
||||
|
||||
Reference in new issue
Block a user