docs(handbook): написаны четыре главы путеводителя

Зачем: после главы о хранилище путеводитель обещал еще четыре главы, а
вместо них стояли заглушки «Пока главы нет…». Без них читатель не видит,
кто двигает мир и раскладывает данные по слоям, куда смотреть в Grafana,
как витрина становится графиком и откуда берутся данные.

Что: docs/handbook/airflow-dags.md, monitoring.md, superset.md,
generator.md — по скелетам тикета #220, форма — как у главы о хранилище.
Сквозная линия трех глав: ход мира на день D везет слепок заказов дня D−1,
поэтому выручка всегда на день позади кликстрима. README путеводителя
ведет заголовками в файлы глав, заглушки убраны; «Куда дальше» главы о
хранилище ведет прямо в главу об Airflow.

Проверка: три SELECT из глав прогнаны на живом стенде от analyst — трафик
получил сыгранный день, выручка только предыдущий, счетчики первых восьми
дней совпали с паспортом мира. Скрипт проверки ссылок и запретных слов из
тикета пуст. Постановка отревьюена Opus (18 находок внесены); главы прошли
саморевью Sol и два слепых ревью Opus — факты и проза (ai-text-lint плюс
оптика литературного русского): 25 находок внесены, 1 отклонена.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ddadminandClaude Fable 5.1 committed 2026-09-02 17:14:43 -04:00
1 parent b15d5253ee
commit ac21399fe4
6 files changed
+306 -16

No files matched your search

+10 -15
View File
@@ -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).
+113
View File
@@ -0,0 +1,113 @@
# Потоки 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`, номер первого несыгранного
дня. Шаговый даг ставит ее только после успешного дня: оборванный прогон позицию
не двигает.
Сыграв день D, шаговый даг отправляет слепок заказов дня D−1 и ждет
`orders_ingest`. Эти связи разобраны в [справочнике
мира](../architecture/world.md#даги-модельного-времени).
## Дневной конвейер
У `etl_pipeline` нет своей обработки. Он по очереди запускает `dds_transform`,
`dm_transform` и `dq_check` и ждет каждый даг. Параметров нет: объем работы
конвейер выводит из позиции мира и состояния слоев. Поэтому один и тот же запуск
верен и когда его запустил другой даг, и когда вы нажали кнопку, и когда его
повторяют после сбоя. Детали есть в [справочнике
конвейера](../architecture/etl.md#объём-прогона).
`world_next_day` не запускает конвейер. После пакетного шага слои догоняют мир
только по вашей команде. `world_live_day`, наоборот, запускает `etl_pipeline` и
ждет его. Поэтому даг остается в работе и после конца модельного дня.
## Что значит красный
Красный `etl_pipeline` не отменяет сыгранного дня: позиция уже записана. Чинится
он перезапуском рукой — помнить о прошлом прогоне ничего не нужно. Кто запускает
конвейер, описано в [разделе о трех путях
запуска](../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).
+57
View File
@@ -0,0 +1,57 @@
# Генератор: откуда берутся данные
Генератор притворяется двумя системами магазина. Счетчик сайта шлет события в
топик `hits`. Бэкенд раз в модельные сутки выгружает слепок заказов в топик
`orders`.
## Что он производит
Событие — широкая строка по образцу выгрузки Яндекс Метрики. Генератор создает
три вида событий: просмотр страницы, корзину и покупку. Все колонки перечислены
в [описании выгрузки](../formats/clickstream-event.md).
Заказ — вторая проекция той же покупки, с деньгами магазина. Заказ ездит в
слепках, пока может измениться, — семь модельных дней. Устройство и форму слепка
разбирает [отдельный справочник](../architecture/orders/snapshot.md).
## Почему данные всегда одни и те же
Модельный день зависит от [зерна](../architecture/generator/seeds.md) — числа,
из которого генератор разворачивает всю свою случайность, — и от номера дня.
Одна и та же пара дает те же события, поэтому стартовый мир одинаков при каждом
`make up`.
Паспорт `data/world-inventory.json` отвечает на один вопрос: тот ли это мир. Он
охватывает только восемь дней стартового мира.
## Кто его запускает
На стенде генератором управляют [даги модельного
времени](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): числа совпадут. Дни, сыгранные после
стартового мира, в паспорте не записаны. Это ожидаемо.
## Куда дальше
Глубже генератор разобран в [`generator/`](../../generator/README.md) и в
[справочнике его устройства](../architecture/generator/README.md). Тропа
путеводителя закончена: дальше идут справочники и [учебные
задания](../labs/README.md).
+68
View File
@@ -0,0 +1,68 @@
# Мониторинг: куда смотреть
В Grafana три дашборда, и у каждого свой вопрос. «Данные» спрашивает, все ли в
порядке с потоком. «Кластер» спрашивает, что с машиной. «Запросы» — что
выполнялось и во что обошлось.
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).
+1 -1
View File
@@ -135,4 +135,4 @@ ORDER BY revenue DESC;
Список объектов, сроки хранения и устройство таблиц — в [справочнике Список объектов, сроки хранения и устройство таблиц — в [справочнике
хранилища](../architecture/storage.md). Как данные переносят между слоями — в хранилища](../architecture/storage.md). Как данные переносят между слоями — в
следующей главе: [потоки Airflow и даги модельного следующей главе: [потоки Airflow и даги модельного
времени](README.md#потоки-airflow-и-даги-модельного-времени). времени](airflow-dags.md).
+57
View File
@@ -0,0 +1,57 @@
# Немного Superset
Superset — это витрины глазами. Он читает слой DM пользователем `bi`. На
дашборде стенда «Бизнес-сюжеты» три графика:
| График | Витрина |
|---|---|
| «Выручка по дням и категориям» | `dm.revenue_daily_v` |
| «Сверка purchase и заказов» | `dm.purchase_vs_orders_v` |
| «Посетители и известные пользователи» | `dm.daily_traffic_v` |
## Как витрина становится графиком
Путь состоит из трех объектов: датасет → график → дашборд. Датасет описывает
витрину: он несет русские имена колонок и формат денег. График ссылается на эти
имена и задает способ показа. Дашборд собирает готовые графики на одном экране.
## Свое и стендовое
Стендовые объекты приезжают из файлов при каждом `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).