From ac21399fe419860be7cd60a933f1964f1e9afc21 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Wed, 2 Sep 2026 17:14:43 -0400 Subject: [PATCH 1/2] =?UTF-8?q?docs(handbook):=20=D0=BD=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D1=8B=20=D1=87=D0=B5=D1=82=D1=8B=D1=80=D0=B5?= =?UTF-8?q?=20=D0=B3=D0=BB=D0=B0=D0=B2=D1=8B=20=D0=BF=D1=83=D1=82=D0=B5?= =?UTF-8?q?=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Зачем: после главы о хранилище путеводитель обещал еще четыре главы, а вместо них стояли заглушки «Пока главы нет…». Без них читатель не видит, кто двигает мир и раскладывает данные по слоям, куда смотреть в 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 --- docs/handbook/README.md | 25 +++---- docs/handbook/airflow-dags.md | 113 ++++++++++++++++++++++++++++++++ docs/handbook/generator.md | 57 ++++++++++++++++ docs/handbook/monitoring.md | 68 +++++++++++++++++++ docs/handbook/storage-layers.md | 2 +- docs/handbook/superset.md | 57 ++++++++++++++++ 6 files changed, 306 insertions(+), 16 deletions(-) create mode 100644 docs/handbook/airflow-dags.md create mode 100644 docs/handbook/generator.md create mode 100644 docs/handbook/monitoring.md create mode 100644 docs/handbook/superset.md diff --git a/docs/handbook/README.md b/docs/handbook/README.md index c57de76..ab95d89 100644 --- a/docs/handbook/README.md +++ b/docs/handbook/README.md @@ -11,8 +11,8 @@ [уроки](../labs/README.md). Словарь не надо читать подряд. Возвращайтесь к нему за незнакомым словом. -Первая статья объясняет хранилище. Следом идет несколько статей об устройстве -генератора; они понадобятся нескоро. +Первая статья словаря объясняет хранилище. Следом идет несколько статей об +устройстве генератора; они понадобятся нескоро. ## Главы @@ -21,28 +21,23 @@ От события в 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). +хранилище. diff --git a/docs/handbook/airflow-dags.md b/docs/handbook/airflow-dags.md new file mode 100644 index 0000000..ada6d31 --- /dev/null +++ b/docs/handbook/airflow-dags.md @@ -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). diff --git a/docs/handbook/generator.md b/docs/handbook/generator.md new file mode 100644 index 0000000..65b3e98 --- /dev/null +++ b/docs/handbook/generator.md @@ -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). diff --git a/docs/handbook/monitoring.md b/docs/handbook/monitoring.md new file mode 100644 index 0000000..409aba1 --- /dev/null +++ b/docs/handbook/monitoring.md @@ -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). diff --git a/docs/handbook/storage-layers.md b/docs/handbook/storage-layers.md index 8fa9be8..26624b1 100644 --- a/docs/handbook/storage-layers.md +++ b/docs/handbook/storage-layers.md @@ -135,4 +135,4 @@ ORDER BY revenue DESC; Список объектов, сроки хранения и устройство таблиц — в [справочнике хранилища](../architecture/storage.md). Как данные переносят между слоями — в следующей главе: [потоки Airflow и даги модельного -времени](README.md#потоки-airflow-и-даги-модельного-времени). +времени](airflow-dags.md). diff --git a/docs/handbook/superset.md b/docs/handbook/superset.md new file mode 100644 index 0000000..7b48c30 --- /dev/null +++ b/docs/handbook/superset.md @@ -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). -- 2.54.0 From 043d1c1382115cd28264a825c54f7f9bf43754a9 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Thu, 3 Sep 2026 02:00:37 -0400 Subject: [PATCH 2/2] =?UTF-8?q?docs(handbook):=20=D1=87=D0=B5=D1=82=D1=8B?= =?UTF-8?q?=D1=80=D0=B5=20=D0=B3=D0=BB=D0=B0=D0=B2=D1=8B=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D1=8B=20=D0=B6=D0=B8?= =?UTF-8?q?=D0=B2=D1=8B=D0=BC=20=D1=80=D1=83=D1=81=D1=81=D0=BA=D0=B8=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Зачем: владелец прочел главы и нашел неестественные фразы: дашборды «спрашивают», даги «двигают ось», заказ «ездит в слепках», Superset — «витрины глазами», объекты «приезжают из файлов». Читателю такие образы надо расшифровывать, а урок в них не прячется. Что: в четырех главах олицетворения заменены прямыми формулировками, «позиция мира» и «шаговый даг» раскрыты через world_position и имена дагов, паспорт мира описан по составу и назначению, окно слепка заказов объяснено словами, режимы генератора и правило импорта Superset сказаны прямо. Тире и стрелки оставлены: это домашний стиль. Проверка: проверки тикета #220 на битые ссылки и запретные слова пусты, строки прозы не длиннее 80 знаков, git diff --check чист. Co-Authored-By: Claude Fable 5.1 --- docs/handbook/airflow-dags.md | 68 ++++++++++++++++++----------------- docs/handbook/generator.md | 43 ++++++++++++---------- docs/handbook/monitoring.md | 57 +++++++++++++++-------------- docs/handbook/superset.md | 35 ++++++++++-------- 4 files changed, 110 insertions(+), 93 deletions(-) diff --git a/docs/handbook/airflow-dags.md b/docs/handbook/airflow-dags.md index ada6d31..dc54499 100644 --- a/docs/handbook/airflow-dags.md +++ b/docs/handbook/airflow-dags.md @@ -1,7 +1,7 @@ # Потоки Airflow и даги модельного времени -В Airflow есть два рода дагов. Даги модельного времени двигают мир вперед, а -дневной конвейер раскладывает прожитый день по слоям. +В Airflow два рода дагов. Даги мира создают мир и проигрывают модельные дни, +а дневной конвейер раскладывает сыгранный день по слоям хранилища. ```mermaid flowchart LR @@ -18,21 +18,21 @@ flowchart LR материализованные представления переносят строки из STG в ODS без участия Airflow. -Заказы приходят в топик `orders` слепком раз в модельные сутки. У слепка есть -начало и конец, поэтому даг `orders_ingest` забирает его целиком. Такой способ -приема называется [пакетным забором](../../CONTEXT.md). +Заказы приходят в топик `orders` один раз в модельные сутки, целым слепком. У +слепка есть начало и конец, поэтому даг `orders_ingest` забирает его одной +порцией. Такой способ приема называется [пакетным](../../CONTEXT.md). ## Даги мира -Два дага с тегом «жизненный цикл мира» создают мир: +Два дага с тегом «жизненный цикл мира» отвечают за стартовый мир: | Даг | Что делает | |---|---| | `world_initialize` | Создает стартовый мир, если его еще нет | -| `world_recreate` | Удаляет только прикладной мир и создает его заново | +| `world_recreate` | Стирает данные мира и собирает стартовый мир заново | -Три дага с тегом «модельное время» двигают ось. Дагами модельного времени -называют только их. +Три дага с тегом «модельное время» проигрывают следующие дни. Именно их +называют дагами модельного времени. | Даг | Что делает | |---|---| @@ -40,43 +40,47 @@ Airflow. | `world_live_day` | Играет следующий день в темпе модельного времени | | `world_live` | Запускает живые дни один за другим, пока снят с паузы | -Позиция мира — переменная Airflow `world_position`, номер первого несыгранного -дня. Шаговый даг ставит ее только после успешного дня: оборванный прогон позицию -не двигает. +Сколько дней уже сыграно, стенд помнит в переменной Airflow `world_position`: +в ней лежит номер первого несыгранного дня. `world_next_day` и `world_live_day` +записывают новое значение только после успешно сыгранного дня; оборванный +прогон его не меняет. -Сыграв день D, шаговый даг отправляет слепок заказов дня D−1 и ждет -`orders_ingest`. Эти связи разобраны в [справочнике +Сыграв день D, эти два дага отправляют слепок заказов за день D−1 и ждут, пока +`orders_ingest` его примет. Эти связи разобраны в [справочнике мира](../architecture/world.md#даги-модельного-времени). ## Дневной конвейер У `etl_pipeline` нет своей обработки. Он по очереди запускает `dds_transform`, -`dm_transform` и `dq_check` и ждет каждый даг. Параметров нет: объем работы -конвейер выводит из позиции мира и состояния слоев. Поэтому один и тот же запуск -верен и когда его запустил другой даг, и когда вы нажали кнопку, и когда его -повторяют после сбоя. Детали есть в [справочнике -конвейера](../architecture/etl.md#объём-прогона). +`dm_transform` и `dq_check` и ждет каждый даг. Параметров у него нет: сколько +дней обработать, он сам определяет по `world_position` и по тому, что уже лежит +в слоях. Поэтому один и тот же запуск верен и когда его запустил другой даг, и +когда вы нажали кнопку, и когда его повторяют после сбоя. Детали есть в +[справочнике конвейера](../architecture/etl.md#объём-прогона). -`world_next_day` не запускает конвейер. После пакетного шага слои догоняют мир -только по вашей команде. `world_live_day`, наоборот, запускает `etl_pipeline` и -ждет его. Поэтому даг остается в работе и после конца модельного дня. +`world_next_day` не запускает конвейер. После него слои хранилища отстают от +мира, пока вы не запустите конвейер сами. `world_live_day`, наоборот, +запускает `etl_pipeline` и ждет его. Поэтому даг остается в работе и после +конца модельного дня. ## Что значит красный -Красный `etl_pipeline` не отменяет сыгранного дня: позиция уже записана. Чинится -он перезапуском рукой — помнить о прошлом прогоне ничего не нужно. Кто запускает -конвейер, описано в [разделе о трех путях -запуска](../architecture/etl.md#три-пути-запуска). +Красный `etl_pipeline` не отменяет сыгранного дня: `world_position` уже +записана. Достаточно перезапустить конвейер рукой; разбираться, на чем +остановился прошлый прогон, не нужно. Кто запускает конвейер, описано в +[разделе о трех путях запуска](../architecture/etl.md#три-пути-запуска). -Контур DQ проверяет данные. В дневном конвейере это `dq_check`: красная задача -печатает нарушенные ключи. Состав проверок описан в [разделе «Звено DQ +Качество данных проверяет контур DQ. В дневном конвейере это даг `dq_check`: +упавшая задача печатает в лог ключи строк, не прошедших проверку. Состав +проверок описан в [разделе «Звено DQ конвейера»](../architecture/dm.md#звено-dq-конвейера). ## Как найти в интерфейсе Даги мира ищите по тегам «модельное время» и «жизненный цикл мира». Остальные даги ищите по тегам «заказы», `etl`, `dds`, `dm` и `dq`. `homework_check` с -тегами `dm` и `labs` проверяет домашние работы; о нем расскажут уроки. +тегами `dm` и `labs` проверяет домашние работы; о нем рассказано в учебных +заданиях. ## Посмотрите сами @@ -102,9 +106,9 @@ ORDER BY report_date DESC LIMIT 3; ``` -Трафик получил сыгранный день, а выручка — только предыдущий: с этим ходом -приехал слепок предыдущего дня. Сыгранный день получит выручку на следующем -ходу. +В трафике уже есть сыгранный день, а в выручке только предыдущий: вместе с этим +днем пришел слепок заказов за предыдущий. Выручка сыгранного дня появится после +следующего. ## Куда дальше diff --git a/docs/handbook/generator.md b/docs/handbook/generator.md index 65b3e98..ea97a5a 100644 --- a/docs/handbook/generator.md +++ b/docs/handbook/generator.md @@ -1,8 +1,8 @@ # Генератор: откуда берутся данные -Генератор притворяется двумя системами магазина. Счетчик сайта шлет события в -топик `hits`. Бэкенд раз в модельные сутки выгружает слепок заказов в топик -`orders`. +Генератор изображает две системы интернет-магазина. Первая — счетчик на сайте, +он шлет события в топик `hits`. Вторая — бэкенд магазина, он раз в модельные +сутки выгружает слепок заказов в топик `orders`. ## Что он производит @@ -10,19 +10,23 @@ три вида событий: просмотр страницы, корзину и покупку. Все колонки перечислены в [описании выгрузки](../formats/clickstream-event.md). -Заказ — вторая проекция той же покупки, с деньгами магазина. Заказ ездит в -слепках, пока может измениться, — семь модельных дней. Устройство и форму слепка -разбирает [отдельный справочник](../architecture/orders/snapshot.md). +Заказ — та же покупка, но записанная бэкендом магазина, с суммами в деньгах. +Семь модельных дней после оформления заказ еще может измениться, поэтому каждый +дневной слепок несет заказы за последние семь дней в их текущем состоянии. +Устройство и форма слепка разобраны в [отдельном +справочнике](../architecture/orders/snapshot.md). ## Почему данные всегда одни и те же -Модельный день зависит от [зерна](../architecture/generator/seeds.md) — числа, -из которого генератор разворачивает всю свою случайность, — и от номера дня. -Одна и та же пара дает те же события, поэтому стартовый мир одинаков при каждом -`make up`. +Генератор не берет случайность извне. Все его случайные решения выводятся из +[зерна](../architecture/generator/seeds.md) — одного числа в настройках — и из +номера дня. То же зерно и тот же номер дня дают ровно те же события, поэтому +стартовый мир одинаков при каждом `make up`. -Паспорт `data/world-inventory.json` отвечает на один вопрос: тот ли это мир. Он -охватывает только восемь дней стартового мира. +Рядом лежит паспорт мира, `data/world-inventory.json`: зерно, версия генератора +и по строке на каждый день с числом событий и контрольной суммой. По нему +проверяют, что генератор собрал тот же мир, что и раньше, и что в ODS все +доехало без потерь. Паспорт описывает только восемь дней стартового мира. ## Кто его запускает @@ -30,8 +34,9 @@ времени](airflow-dags.md#даги-мира). Его можно запустить и напрямую. Команды собраны в [справочнике мира](../architecture/world.md#как-запустить-генератор). -У генератора два режима. Пакетный отправляет день пачкой. Живой проигрывает -модельные сутки в ускоренном темпе. +У генератора два режима. Пакетный отправляет весь день разом. Живой шлет +события по ходу модельных суток; сутки идут ускоренно и занимают около двадцати +четырех минут. ## Посмотрите сами @@ -47,11 +52,11 @@ ORDER BY EventDate; Сравните первые восемь дней с восемью строками в [паспорте мира](../../data/world-inventory.json): числа совпадут. Дни, сыгранные после -стартового мира, в паспорте не записаны. Это ожидаемо. +стартового мира, в паспорте не записаны. Так и задумано. ## Куда дальше -Глубже генератор разобран в [`generator/`](../../generator/README.md) и в -[справочнике его устройства](../architecture/generator/README.md). Тропа -путеводителя закончена: дальше идут справочники и [учебные -задания](../labs/README.md). +Подробнее генератор разобран в [README папки +`generator/`](../../generator/README.md) и в [справочнике его +устройства](../architecture/generator/README.md). На этом путеводитель +заканчивается: дальше справочники и [учебные задания](../labs/README.md). diff --git a/docs/handbook/monitoring.md b/docs/handbook/monitoring.md index 409aba1..fbbd82c 100644 --- a/docs/handbook/monitoring.md +++ b/docs/handbook/monitoring.md @@ -1,49 +1,52 @@ # Мониторинг: куда смотреть -В Grafana три дашборда, и у каждого свой вопрос. «Данные» спрашивает, все ли в -порядке с потоком. «Кластер» спрашивает, что с машиной. «Запросы» — что -выполнялось и во что обошлось. +В Grafana три дашборда, и у каждого своя тема. «Данные» показывает, все ли в +порядке с потоком данных. «Кластер» — состояние машин и самого ClickHouse. +«Запросы» — какие запросы выполнялись и сколько ресурсов они заняли. Prometheus собирает метрики с двух узлов ClickHouse, keeper и экспортера Kafka. Grafana читает и Prometheus, и ClickHouse напрямую. На панелях нет порогов и -цветовых оценок: на них смотрят глазами. Красное и зеленое живут в проверках и -дагах DQ. +цветовой подсветки: оценивать картинку придется самому. Автоматические +проверки, которые выносят вердикт, собраны в контуре DQ. ## Дашборд «Данные» -«Свежесть» отвечает, давно ли в ODS появились последние события и заказы. -Свежесть заказов растет весь модельный день и падает, когда на границе суток -приезжает слепок. Так устроен источник, а не сломан стенд. +«Свежесть» показывает, сколько времени прошло с последнего события и с +последнего заказа в ODS. Свежесть заказов растет весь модельный день и +сбрасывается, когда на границе суток приходит слепок. Это нормальное поведение +источника, а не поломка. -«Поток» показывает число сырых сообщений в STG за выбранный интервал. Рядом -«Брак» отвечает, какая часть приехавших строк не прошла разбор. +«Поток» показывает число сырых сообщений в STG за выбранный интервал. «Брак» +рядом — доля строк, которые не удалось разобрать. -«Сходимость» ставит рядом число событий из Kafka и ClickHouse. Ищите устойчивый -разрыв между линиями: разница в один столбец ничего не значит. +«Сходимость» сравнивает число событий в Kafka и в ClickHouse. Тревожный +признак — устойчивый разрыв между линиями. Расхождение в одном столбце ничего +не значит. -«Отставание» показывает, остались ли у читателей Kafka непрочитанные сообщения. -«Дневной слепок» показывает последние десять слепков заказов в STG: по нему -видно, доехала ли выгрузка вовремя. +«Отставание» показывает, сколько сообщений в Kafka еще не прочитано +потребителями. «Дневной слепок» перечисляет последние десять слепков заказов в +STG: по нему видно, пришла ли выгрузка вовремя. Источники и правила чтения всех панелей разобраны в [справочнике дашборда «Данные»](../architecture/monitoring/data.md). -## Почему панели смотрят в разные слои +## Почему у панелей разные источники -Свежесть спрашивают у ODS: именно там видно, что разбор встал. Поток и брак -считают по STG, где сохраняется каждая доставка. ODS может схлопнуть повтор -события или версии заказа и занизить счетчик. Подробности — в [разделе о слоях +Свежесть считается по ODS: если разбор остановился, это видно именно там. Поток +и брак считаются по STG, где сохраняется каждое доставленное сообщение. В ODS +повторы события и старые версии заказа схлопываются, поэтому счетчик там был бы +занижен. Подробности — в [разделе о слоях панелей](../architecture/monitoring/data.md#почему-слои-у-панелей-разные). ## Два других дашборда -Открывайте «Кластер», когда нужно понять, что происходит с процессором, памятью, -дисками, частями и слияниями ClickHouse, keeper или очередью DDL. Устройство -панелей описано в [справочнике дашборда +Открывайте «Кластер», когда нужно понять, что происходит с процессором, памятью +и дисками, с кусками данных и их слияниями в ClickHouse, с keeper или очередью +DDL. Устройство панелей описано в [справочнике дашборда «Кластер»](../architecture/monitoring/cluster.md). -«Запросы» нужен, когда вы ищете тяжелые запросы, ошибки или расход ресурсов по -пользователям. Как читать списки, объясняет [справочник дашборда +«Запросы» пригодится, когда вы ищете тяжелые запросы, ошибки или расход +ресурсов по пользователям. Как читать списки, объясняет [справочник дашборда «Запросы»](../architecture/monitoring/queries.md). ## Посмотрите сами @@ -55,9 +58,9 @@ Airflow [`world_live_day`](airflow-dags.md#даги-мира): модельны Смотрите свежесть событий и свежесть заказов по отдельности. Пока день идет, свежесть событий держится на секундах, а свежесть заказов растет. На границе дня -слепок уезжает сразу: свежесть заказов падает, а свежесть событий начинает -расти. Сам даг остается в работе и после конца дня, потому что ждет дневной -конвейер. +слепок отправляется сразу: свежесть заказов сбрасывается, а свежесть событий +начинает расти, потому что новых событий до следующего дня не будет. Сам даг +остается в работе и после конца дня, потому что ждет дневной конвейер. ## Куда дальше diff --git a/docs/handbook/superset.md b/docs/handbook/superset.md index 7b48c30..e91863c 100644 --- a/docs/handbook/superset.md +++ b/docs/handbook/superset.md @@ -1,7 +1,8 @@ # Немного Superset -Superset — это витрины глазами. Он читает слой DM пользователем `bi`. На -дашборде стенда «Бизнес-сюжеты» три графика: +Superset показывает витрины слоя DM в виде графиков. К ClickHouse он +подключается пользователем `bi`. На дашборде стенда «Бизнес-сюжеты» три +графика: | График | Витрина | |---|---| @@ -11,26 +12,30 @@ Superset — это витрины глазами. Он читает слой DM ## Как витрина становится графиком -Путь состоит из трех объектов: датасет → график → дашборд. Датасет описывает -витрину: он несет русские имена колонок и формат денег. График ссылается на эти -имена и задает способ показа. Дашборд собирает готовые графики на одном экране. +От витрины до экрана три объекта Superset: датасет → график → дашборд. Датасет +описывает витрину: задает русские имена колонок и формат денег. График +ссылается на эти имена и задает способ показа. Дашборд собирает готовые графики +на одном экране. -## Свое и стендовое +## Стендовые объекты и ваши -Стендовые объекты приезжают из файлов при каждом `make up`. Правка такого -датасета, графика или дашборда в интерфейсе живет до следующей инициализации, а -затем молча заменяется версией из репозитория. +Датасеты, графики и дашборд из поставки стенда лежат файлами в репозитории и +заново импортируются при каждом `make up`. Если поправить такой объект в +интерфейсе, правка проживет до следующего `make up`, а потом без предупреждения +заменится версией из файла. -Ваши объекты живут рядом в базе метаданных Superset. Они переживают `make up` и -`make rebuild-storage`. Только `make clean` стирает их вместе с остальным -постоянным состоянием стенда. Поэтому стендовые объекты оставляйте как есть, а -свои отчеты стройте рядом. Устройство импорта описано в [справочнике +Ваши собственные объекты хранятся в той же базе метаданных Superset, но импорт +их не трогает: они переживают и `make up`, и `make rebuild-storage`. Стирает их +только `make clean` вместе с остальным постоянным состоянием стенда. Поэтому +стендовые объекты оставляйте как есть, а свои отчеты стройте рядом. Устройство +импорта описано в [справочнике Superset](../architecture/superset.md#импорт-при-каждой-инициализации). ## Почему края графиков не совпадают -Правый край выручки всегда на день позади кликстрима. Слепок заказов дня -приезжает со следующим ходом мира. Так устроен источник. Вы уже видели этот +Правый край графика выручки всегда на день позади графиков кликстрима. Слепок +заказов за день приходит только со следующим модельным днем. Так устроен +источник, а не витрина. Вы уже видели этот сдвиг в [главе об Airflow](airflow-dags.md#посмотрите-сами). Начальное состояние показано в разделе [«Стартовый мир»](../architecture/world.md#стартовый-мир). -- 2.54.0