Merge pull request 'docs(handbook): четыре главы путеводителя — Airflow, мониторинг, Superset, генератор' (#221) from 220-handbook-chapters into main
Reviewed-on: #221
This commit was merged in pull request #221.
This commit is contained in:
commit
4995628f2a
6 files changed
+323
-16
No files matched your search
+10
-15
@@ -11,8 +11,8 @@
|
|||||||
[уроки](../labs/README.md).
|
[уроки](../labs/README.md).
|
||||||
|
|
||||||
Словарь не надо читать подряд. Возвращайтесь к нему за незнакомым словом.
|
Словарь не надо читать подряд. Возвращайтесь к нему за незнакомым словом.
|
||||||
Первая статья объясняет хранилище. Следом идет несколько статей об устройстве
|
Первая статья словаря объясняет хранилище. Следом идет несколько статей об
|
||||||
генератора; они понадобятся нескоро.
|
устройстве генератора; они понадобятся нескоро.
|
||||||
|
|
||||||
## Главы
|
## Главы
|
||||||
|
|
||||||
@@ -21,28 +21,23 @@
|
|||||||
От события в Kafka до витрины: глава разбирает путь через STG, ODS, DDS и DM
|
От события в Kafka до витрины: глава разбирает путь через STG, ODS, DDS и DM
|
||||||
и показывает, за что отвечает каждый слой.
|
и показывает, за что отвечает каждый слой.
|
||||||
|
|
||||||
### Потоки Airflow и даги модельного времени
|
### [Потоки Airflow и даги модельного времени](airflow-dags.md)
|
||||||
|
|
||||||
Шаговый даг играет модельный день, а дневной конвейер раскладывает данные по
|
Шаговый даг играет модельный день, а дневной конвейер раскладывает данные по
|
||||||
слоям. Глава поможет увидеть их связь и роль каждого дага. Пока главы нет,
|
слоям. Глава поможет увидеть их связь и роль каждого дага.
|
||||||
смотрите [справочник конвейера](../architecture/etl.md) и [справочник мира и
|
|
||||||
дагов времени](../architecture/world.md).
|
|
||||||
|
|
||||||
### Мониторинг: куда смотреть
|
### [Мониторинг: куда смотреть](monitoring.md)
|
||||||
|
|
||||||
Свежесть и поток данных, брак и отставание собраны на дашборде «Данные».
|
Свежесть и поток данных, брак и отставание собраны на дашборде «Данные».
|
||||||
Глава научит находить нужную панель и разбирать ее показания. Пока главы
|
Глава научит находить нужную панель и разбирать ее показания.
|
||||||
нет, смотрите [устройство мониторинга](../architecture/monitoring/README.md).
|
|
||||||
|
|
||||||
### Немного Superset
|
### [Немного Superset](superset.md)
|
||||||
|
|
||||||
Глава покажет, как витрина становится графиком и где проходит граница между
|
Глава покажет, как витрина становится графиком и где проходит граница между
|
||||||
своими объектами и теми, которые поднимает стенд. Пока главы нет, смотрите
|
своими объектами и теми, которые поднимает стенд.
|
||||||
[справочник Superset](../architecture/superset.md).
|
|
||||||
|
|
||||||
### Генератор: откуда берутся данные
|
### [Генератор: откуда берутся данные](generator.md)
|
||||||
|
|
||||||
Здесь генератор — источник данных, а не предмет изучения. Глава в общих
|
Здесь генератор — источник данных, а не предмет изучения. Глава в общих
|
||||||
чертах объяснит, откуда берутся события и заказы и в каком виде их получает
|
чертах объяснит, откуда берутся события и заказы и в каком виде их получает
|
||||||
хранилище. Пока главы нет, смотрите [`generator/`](../../generator/) и
|
хранилище.
|
||||||
[описание события кликстрима](../formats/clickstream-event.md).
|
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
# Потоки Airflow и даги модельного времени
|
||||||
|
|
||||||
|
В Airflow два рода дагов. Даги мира создают мир и проигрывают модельные дни,
|
||||||
|
а дневной конвейер раскладывает сыгранный день по слоям хранилища.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
world_initialize --> etl_pipeline
|
||||||
|
world_live_day --> etl_pipeline
|
||||||
|
manual[запуск рукой] --> etl_pipeline
|
||||||
|
etl_pipeline --> dds_transform --> dm_transform --> dq_check
|
||||||
|
world_next_day --> sources[источники без ETL]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Два потока входят по-разному
|
||||||
|
|
||||||
|
События приходят в топик `hits`. Хранилище разбирает их само и непрерывно:
|
||||||
|
материализованные представления переносят строки из STG в ODS без участия
|
||||||
|
Airflow.
|
||||||
|
|
||||||
|
Заказы приходят в топик `orders` один раз в модельные сутки, целым слепком. У
|
||||||
|
слепка есть начало и конец, поэтому даг `orders_ingest` забирает его одной
|
||||||
|
порцией. Такой способ приема называется [пакетным](../../CONTEXT.md).
|
||||||
|
|
||||||
|
## Даги мира
|
||||||
|
|
||||||
|
Два дага с тегом «жизненный цикл мира» отвечают за стартовый мир:
|
||||||
|
|
||||||
|
| Даг | Что делает |
|
||||||
|
|---|---|
|
||||||
|
| `world_initialize` | Создает стартовый мир, если его еще нет |
|
||||||
|
| `world_recreate` | Стирает данные мира и собирает стартовый мир заново |
|
||||||
|
|
||||||
|
Три дага с тегом «модельное время» проигрывают следующие дни. Именно их
|
||||||
|
называют дагами модельного времени.
|
||||||
|
|
||||||
|
| Даг | Что делает |
|
||||||
|
|---|---|
|
||||||
|
| `world_next_day` | Играет следующие дни пачкой |
|
||||||
|
| `world_live_day` | Играет следующий день в темпе модельного времени |
|
||||||
|
| `world_live` | Запускает живые дни один за другим, пока снят с паузы |
|
||||||
|
|
||||||
|
Сколько дней уже сыграно, стенд помнит в переменной Airflow `world_position`:
|
||||||
|
в ней лежит номер первого несыгранного дня. `world_next_day` и `world_live_day`
|
||||||
|
записывают новое значение только после успешно сыгранного дня; оборванный
|
||||||
|
прогон его не меняет.
|
||||||
|
|
||||||
|
Сыграв день D, эти два дага отправляют слепок заказов за день D−1 и ждут, пока
|
||||||
|
`orders_ingest` его примет. Эти связи разобраны в [справочнике
|
||||||
|
мира](../architecture/world.md#даги-модельного-времени).
|
||||||
|
|
||||||
|
## Дневной конвейер
|
||||||
|
|
||||||
|
У `etl_pipeline` нет своей обработки. Он по очереди запускает `dds_transform`,
|
||||||
|
`dm_transform` и `dq_check` и ждет каждый даг. Параметров у него нет: сколько
|
||||||
|
дней обработать, он сам определяет по `world_position` и по тому, что уже лежит
|
||||||
|
в слоях. Поэтому один и тот же запуск верен и когда его запустил другой даг, и
|
||||||
|
когда вы нажали кнопку, и когда его повторяют после сбоя. Детали есть в
|
||||||
|
[справочнике конвейера](../architecture/etl.md#объём-прогона).
|
||||||
|
|
||||||
|
`world_next_day` не запускает конвейер. После него слои хранилища отстают от
|
||||||
|
мира, пока вы не запустите конвейер сами. `world_live_day`, наоборот,
|
||||||
|
запускает `etl_pipeline` и ждет его. Поэтому даг остается в работе и после
|
||||||
|
конца модельного дня.
|
||||||
|
|
||||||
|
## Что значит красный
|
||||||
|
|
||||||
|
Красный `etl_pipeline` не отменяет сыгранного дня: `world_position` уже
|
||||||
|
записана. Достаточно перезапустить конвейер рукой; разбираться, на чем
|
||||||
|
остановился прошлый прогон, не нужно. Кто запускает конвейер, описано в
|
||||||
|
[разделе о трех путях запуска](../architecture/etl.md#три-пути-запуска).
|
||||||
|
|
||||||
|
Качество данных проверяет контур DQ. В дневном конвейере это даг `dq_check`:
|
||||||
|
упавшая задача печатает в лог ключи строк, не прошедших проверку. Состав
|
||||||
|
проверок описан в [разделе «Звено DQ
|
||||||
|
конвейера»](../architecture/dm.md#звено-dq-конвейера).
|
||||||
|
|
||||||
|
## Как найти в интерфейсе
|
||||||
|
|
||||||
|
Даги мира ищите по тегам «модельное время» и «жизненный цикл мира». Остальные
|
||||||
|
даги ищите по тегам «заказы», `etl`, `dds`, `dm` и `dq`. `homework_check` с
|
||||||
|
тегами `dm` и `labs` проверяет домашние работы; о нем рассказано в учебных
|
||||||
|
заданиях.
|
||||||
|
|
||||||
|
## Посмотрите сами
|
||||||
|
|
||||||
|
Откройте Airflow по адресу из раздела [«Адреса и
|
||||||
|
пароли»](../../README.md#адреса-и-пароли). В Admin → Variables найдите
|
||||||
|
`world_position`. Затем запустите `world_next_day` на один день по [инструкции
|
||||||
|
из README](../../README.md#сдвинуть-мир-вперед). Убедитесь, что `orders_ingest`
|
||||||
|
отработал, а витрины еще ничего не получили. Запустите `etl_pipeline` рукой.
|
||||||
|
|
||||||
|
В DBeaver, подключенном по
|
||||||
|
[инструкции](../../README.md#подключиться-из-dbeaver), выполните два запроса:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT report_date, visitors, known_users
|
||||||
|
FROM dm.daily_traffic_v
|
||||||
|
ORDER BY report_date DESC
|
||||||
|
LIMIT 3;
|
||||||
|
|
||||||
|
SELECT report_date, sum(revenue) AS revenue
|
||||||
|
FROM dm.revenue_daily_v
|
||||||
|
GROUP BY report_date
|
||||||
|
ORDER BY report_date DESC
|
||||||
|
LIMIT 3;
|
||||||
|
```
|
||||||
|
|
||||||
|
В трафике уже есть сыгранный день, а в выручке только предыдущий: вместе с этим
|
||||||
|
днем пришел слепок заказов за предыдущий. Выручка сыгранного дня появится после
|
||||||
|
следующего.
|
||||||
|
|
||||||
|
## Куда дальше
|
||||||
|
|
||||||
|
Детали — в справочниках [конвейера](../architecture/etl.md) и
|
||||||
|
[мира](../architecture/world.md). Следующая глава — [«Мониторинг: куда
|
||||||
|
смотреть»](monitoring.md).
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# Генератор: откуда берутся данные
|
||||||
|
|
||||||
|
Генератор изображает две системы интернет-магазина. Первая — счетчик на сайте,
|
||||||
|
он шлет события в топик `hits`. Вторая — бэкенд магазина, он раз в модельные
|
||||||
|
сутки выгружает слепок заказов в топик `orders`.
|
||||||
|
|
||||||
|
## Что он производит
|
||||||
|
|
||||||
|
Событие — широкая строка по образцу выгрузки Яндекс Метрики. Генератор создает
|
||||||
|
три вида событий: просмотр страницы, корзину и покупку. Все колонки перечислены
|
||||||
|
в [описании выгрузки](../formats/clickstream-event.md).
|
||||||
|
|
||||||
|
Заказ — та же покупка, но записанная бэкендом магазина, с суммами в деньгах.
|
||||||
|
Семь модельных дней после оформления заказ еще может измениться, поэтому каждый
|
||||||
|
дневной слепок несет заказы за последние семь дней в их текущем состоянии.
|
||||||
|
Устройство и форма слепка разобраны в [отдельном
|
||||||
|
справочнике](../architecture/orders/snapshot.md).
|
||||||
|
|
||||||
|
## Почему данные всегда одни и те же
|
||||||
|
|
||||||
|
Генератор не берет случайность извне. Все его случайные решения выводятся из
|
||||||
|
[зерна](../architecture/generator/seeds.md) — одного числа в настройках — и из
|
||||||
|
номера дня. То же зерно и тот же номер дня дают ровно те же события, поэтому
|
||||||
|
стартовый мир одинаков при каждом `make up`.
|
||||||
|
|
||||||
|
Рядом лежит паспорт мира, `data/world-inventory.json`: зерно, версия генератора
|
||||||
|
и по строке на каждый день с числом событий и контрольной суммой. По нему
|
||||||
|
проверяют, что генератор собрал тот же мир, что и раньше, и что в ODS все
|
||||||
|
доехало без потерь. Паспорт описывает только восемь дней стартового мира.
|
||||||
|
|
||||||
|
## Кто его запускает
|
||||||
|
|
||||||
|
На стенде генератором управляют [даги модельного
|
||||||
|
времени](airflow-dags.md#даги-мира). Его можно запустить и напрямую. Команды
|
||||||
|
собраны в [справочнике мира](../architecture/world.md#как-запустить-генератор).
|
||||||
|
|
||||||
|
У генератора два режима. Пакетный отправляет весь день разом. Живой шлет
|
||||||
|
события по ходу модельных суток; сутки идут ускоренно и занимают около двадцати
|
||||||
|
четырех минут.
|
||||||
|
|
||||||
|
## Посмотрите сами
|
||||||
|
|
||||||
|
Подключитесь из DBeaver по [инструкции](../../README.md#подключиться-из-dbeaver)
|
||||||
|
и выполните запрос:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT EventDate, count() AS events
|
||||||
|
FROM ods.event_v
|
||||||
|
GROUP BY EventDate
|
||||||
|
ORDER BY EventDate;
|
||||||
|
```
|
||||||
|
|
||||||
|
Сравните первые восемь дней с восемью строками в [паспорте
|
||||||
|
мира](../../data/world-inventory.json): числа совпадут. Дни, сыгранные после
|
||||||
|
стартового мира, в паспорте не записаны. Так и задумано.
|
||||||
|
|
||||||
|
## Куда дальше
|
||||||
|
|
||||||
|
Подробнее генератор разобран в [README папки
|
||||||
|
`generator/`](../../generator/README.md) и в [справочнике его
|
||||||
|
устройства](../architecture/generator/README.md). На этом путеводитель
|
||||||
|
заканчивается: дальше справочники и [учебные задания](../labs/README.md).
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
# Мониторинг: куда смотреть
|
||||||
|
|
||||||
|
В Grafana три дашборда, и у каждого своя тема. «Данные» показывает, все ли в
|
||||||
|
порядке с потоком данных. «Кластер» — состояние машин и самого ClickHouse.
|
||||||
|
«Запросы» — какие запросы выполнялись и сколько ресурсов они заняли.
|
||||||
|
|
||||||
|
Prometheus собирает метрики с двух узлов ClickHouse, keeper и экспортера Kafka.
|
||||||
|
Grafana читает и Prometheus, и ClickHouse напрямую. На панелях нет порогов и
|
||||||
|
цветовой подсветки: оценивать картинку придется самому. Автоматические
|
||||||
|
проверки, которые выносят вердикт, собраны в контуре DQ.
|
||||||
|
|
||||||
|
## Дашборд «Данные»
|
||||||
|
|
||||||
|
«Свежесть» показывает, сколько времени прошло с последнего события и с
|
||||||
|
последнего заказа в ODS. Свежесть заказов растет весь модельный день и
|
||||||
|
сбрасывается, когда на границе суток приходит слепок. Это нормальное поведение
|
||||||
|
источника, а не поломка.
|
||||||
|
|
||||||
|
«Поток» показывает число сырых сообщений в STG за выбранный интервал. «Брак»
|
||||||
|
рядом — доля строк, которые не удалось разобрать.
|
||||||
|
|
||||||
|
«Сходимость» сравнивает число событий в Kafka и в ClickHouse. Тревожный
|
||||||
|
признак — устойчивый разрыв между линиями. Расхождение в одном столбце ничего
|
||||||
|
не значит.
|
||||||
|
|
||||||
|
«Отставание» показывает, сколько сообщений в Kafka еще не прочитано
|
||||||
|
потребителями. «Дневной слепок» перечисляет последние десять слепков заказов в
|
||||||
|
STG: по нему видно, пришла ли выгрузка вовремя.
|
||||||
|
|
||||||
|
Источники и правила чтения всех панелей разобраны в [справочнике дашборда
|
||||||
|
«Данные»](../architecture/monitoring/data.md).
|
||||||
|
|
||||||
|
## Почему у панелей разные источники
|
||||||
|
|
||||||
|
Свежесть считается по ODS: если разбор остановился, это видно именно там. Поток
|
||||||
|
и брак считаются по STG, где сохраняется каждое доставленное сообщение. В ODS
|
||||||
|
повторы события и старые версии заказа схлопываются, поэтому счетчик там был бы
|
||||||
|
занижен. Подробности — в [разделе о слоях
|
||||||
|
панелей](../architecture/monitoring/data.md#почему-слои-у-панелей-разные).
|
||||||
|
|
||||||
|
## Два других дашборда
|
||||||
|
|
||||||
|
Открывайте «Кластер», когда нужно понять, что происходит с процессором, памятью
|
||||||
|
и дисками, с кусками данных и их слияниями в ClickHouse, с keeper или очередью
|
||||||
|
DDL. Устройство панелей описано в [справочнике дашборда
|
||||||
|
«Кластер»](../architecture/monitoring/cluster.md).
|
||||||
|
|
||||||
|
«Запросы» пригодится, когда вы ищете тяжелые запросы, ошибки или расход
|
||||||
|
ресурсов по пользователям. Как читать списки, объясняет [справочник дашборда
|
||||||
|
«Запросы»](../architecture/monitoring/queries.md).
|
||||||
|
|
||||||
|
## Посмотрите сами
|
||||||
|
|
||||||
|
Откройте Grafana по адресу из раздела [«Адреса и
|
||||||
|
пароли»](../../README.md#адреса-и-пароли), затем дашборд «Данные». Запустите в
|
||||||
|
Airflow [`world_live_day`](airflow-dags.md#даги-мира): модельный день займет
|
||||||
|
около двадцати четырех минут.
|
||||||
|
|
||||||
|
Смотрите свежесть событий и свежесть заказов по отдельности. Пока день идет,
|
||||||
|
свежесть событий держится на секундах, а свежесть заказов растет. На границе дня
|
||||||
|
слепок отправляется сразу: свежесть заказов сбрасывается, а свежесть событий
|
||||||
|
начинает расти, потому что новых событий до следующего дня не будет. Сам даг
|
||||||
|
остается в работе и после конца дня, потому что ждет дневной конвейер.
|
||||||
|
|
||||||
|
## Куда дальше
|
||||||
|
|
||||||
|
Состав мониторинга собран в [справочнике
|
||||||
|
зоны](../architecture/monitoring/README.md), детали главного экрана — в
|
||||||
|
[справочнике дашборда «Данные»](../architecture/monitoring/data.md), а границы
|
||||||
|
решения — в [ADR 0002](../adr/0002-monitoring-scope.md). Следующая глава —
|
||||||
|
[«Немного Superset»](superset.md).
|
||||||
@@ -135,4 +135,4 @@ ORDER BY revenue DESC;
|
|||||||
Список объектов, сроки хранения и устройство таблиц — в [справочнике
|
Список объектов, сроки хранения и устройство таблиц — в [справочнике
|
||||||
хранилища](../architecture/storage.md). Как данные переносят между слоями — в
|
хранилища](../architecture/storage.md). Как данные переносят между слоями — в
|
||||||
следующей главе: [потоки Airflow и даги модельного
|
следующей главе: [потоки Airflow и даги модельного
|
||||||
времени](README.md#потоки-airflow-и-даги-модельного-времени).
|
времени](airflow-dags.md).
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# Немного Superset
|
||||||
|
|
||||||
|
Superset показывает витрины слоя DM в виде графиков. К ClickHouse он
|
||||||
|
подключается пользователем `bi`. На дашборде стенда «Бизнес-сюжеты» три
|
||||||
|
графика:
|
||||||
|
|
||||||
|
| График | Витрина |
|
||||||
|
|---|---|
|
||||||
|
| «Выручка по дням и категориям» | `dm.revenue_daily_v` |
|
||||||
|
| «Сверка purchase и заказов» | `dm.purchase_vs_orders_v` |
|
||||||
|
| «Посетители и известные пользователи» | `dm.daily_traffic_v` |
|
||||||
|
|
||||||
|
## Как витрина становится графиком
|
||||||
|
|
||||||
|
От витрины до экрана три объекта Superset: датасет → график → дашборд. Датасет
|
||||||
|
описывает витрину: задает русские имена колонок и формат денег. График
|
||||||
|
ссылается на эти имена и задает способ показа. Дашборд собирает готовые графики
|
||||||
|
на одном экране.
|
||||||
|
|
||||||
|
## Стендовые объекты и ваши
|
||||||
|
|
||||||
|
Датасеты, графики и дашборд из поставки стенда лежат файлами в репозитории и
|
||||||
|
заново импортируются при каждом `make up`. Если поправить такой объект в
|
||||||
|
интерфейсе, правка проживет до следующего `make up`, а потом без предупреждения
|
||||||
|
заменится версией из файла.
|
||||||
|
|
||||||
|
Ваши собственные объекты хранятся в той же базе метаданных Superset, но импорт
|
||||||
|
их не трогает: они переживают и `make up`, и `make rebuild-storage`. Стирает их
|
||||||
|
только `make clean` вместе с остальным постоянным состоянием стенда. Поэтому
|
||||||
|
стендовые объекты оставляйте как есть, а свои отчеты стройте рядом. Устройство
|
||||||
|
импорта описано в [справочнике
|
||||||
|
Superset](../architecture/superset.md#импорт-при-каждой-инициализации).
|
||||||
|
|
||||||
|
## Почему края графиков не совпадают
|
||||||
|
|
||||||
|
Правый край графика выручки всегда на день позади графиков кликстрима. Слепок
|
||||||
|
заказов за день приходит только со следующим модельным днем. Так устроен
|
||||||
|
источник, а не витрина. Вы уже видели этот
|
||||||
|
сдвиг в [главе об Airflow](airflow-dags.md#посмотрите-сами). Начальное состояние
|
||||||
|
показано в разделе [«Стартовый мир»](../architecture/world.md#стартовый-мир).
|
||||||
|
|
||||||
|
## Посмотрите сами
|
||||||
|
|
||||||
|
Откройте Superset по адресу из раздела [«Адреса и
|
||||||
|
пароли»](../../README.md#адреса-и-пароли) и выберите дашборд «Бизнес-сюжеты».
|
||||||
|
Затем откройте SQL Lab и выполните запрос:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT report_date, visitors, known_users
|
||||||
|
FROM dm.daily_traffic_v
|
||||||
|
ORDER BY report_date DESC
|
||||||
|
LIMIT 7;
|
||||||
|
```
|
||||||
|
|
||||||
|
Как построить свой отчет, рассказывают [учебные задания](../labs/README.md).
|
||||||
|
|
||||||
|
## Куда дальше
|
||||||
|
|
||||||
|
Устройство BI-зоны описано в [справочнике
|
||||||
|
Superset](../architecture/superset.md), а состав витрин — в [справочнике
|
||||||
|
DM](../architecture/dm.md). Следующая глава — [«Генератор: откуда берутся
|
||||||
|
данные»](generator.md).
|
||||||
Reference in new issue
Block a user