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
+19
-22
@@ -1,50 +1,47 @@
|
||||
# Путеводитель по стенду
|
||||
|
||||
Если вы впервые видите стенд, начните отсюда. Путеводитель подскажет, на что
|
||||
смотреть и в каком порядке, а за подробностями отправит в справочники. Так вы
|
||||
разберетесь в устройстве, прежде чем браться за уроки.
|
||||
Путеводитель объясняет, как данные поступают в хранилище, обрабатываются
|
||||
и попадают в отчеты. В главах есть короткие примеры, которые можно выполнить
|
||||
на запущенном стенде перед переходом к учебным заданиям.
|
||||
|
||||
## Как читать
|
||||
|
||||
Тропа такая: [словарь понятий](../../CONTEXT.md) → главы путеводителя →
|
||||
[справочники `docs/architecture/`](../architecture/) →
|
||||
[уроки](../labs/README.md).
|
||||
|
||||
Словарь не надо читать подряд. Возвращайтесь к нему за незнакомым словом.
|
||||
Первая статья словаря объясняет хранилище. Следом идет несколько статей об
|
||||
устройстве генератора; они понадобятся нескоро.
|
||||
Читайте главы в порядке ниже. Незнакомые термины можно найти в
|
||||
[словаре понятий](../../CONTEXT.md), а подробности устройства —
|
||||
в [технических справочниках](../architecture/). К ним достаточно обращаться
|
||||
по мере необходимости. После путеводителя переходите к
|
||||
[учебным заданиям](../labs/README.md).
|
||||
|
||||
## Карта хранилища
|
||||
|
||||
[Интерактивная карта](architecture-map.html) показывает путь данных через слои.
|
||||
Gitea показывает HTML как текст. Откройте файл из своей копии репозитория
|
||||
или скачайте его кнопкой «Raw» и откройте в браузере.
|
||||
Держите карту рядом с главой «Хранилище и его слои».
|
||||
Сверяйтесь с картой при чтении главы «Хранилище и его слои».
|
||||
|
||||
## Главы
|
||||
|
||||
### [Хранилище и его слои](storage-layers.md)
|
||||
|
||||
От события в Kafka до витрины: глава разбирает путь через STG, ODS, DDS и DM
|
||||
и показывает, за что отвечает каждый слой.
|
||||
Как меняются данные при переходе из Kafka в слои STG, ODS, DDS и DM.
|
||||
В конце главы вы посмотрите события, сессии и выручку с помощью SQL.
|
||||
|
||||
### [Потоки Airflow и даги модельного времени](airflow-dags.md)
|
||||
|
||||
Шаговый даг играет модельный день, а дневной конвейер раскладывает данные по
|
||||
слоям. Глава поможет увидеть их связь и роль каждого дага.
|
||||
Какие даги создают новые данные, а какие обрабатывают их в хранилище.
|
||||
Вы запустите генерацию и обработку за день и посмотрите результат в витринах.
|
||||
|
||||
### [Мониторинг: куда смотреть](monitoring.md)
|
||||
|
||||
Свежесть и поток данных, брак и отставание собраны на дашборде «Данные».
|
||||
Глава научит находить нужную панель и разбирать ее показания.
|
||||
Что показывают панели Grafana и как меняются их показания, пока в стенд
|
||||
поступают события и заказы.
|
||||
|
||||
### [Немного Superset](superset.md)
|
||||
|
||||
Глава покажет, как витрина становится графиком и где проходит граница между
|
||||
своими объектами и теми, которые поднимает стенд.
|
||||
Как Superset строит графики по витринам и что происходит с вашими отчетами
|
||||
при перезапуске стенда.
|
||||
|
||||
### [Генератор: откуда берутся данные](generator.md)
|
||||
|
||||
Здесь генератор — источник данных, а не предмет изучения. Глава в общих
|
||||
чертах объяснит, откуда берутся события и заказы и в каком виде их получает
|
||||
хранилище.
|
||||
Откуда берутся события и заказы, почему начальные данные повторяются
|
||||
и как сверить число загруженных событий с ожидаемым.
|
||||
@@ -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 и запуска конвейера.
|
||||
|
||||
## Куда дальше
|
||||
|
||||
|
||||
+34
-26
@@ -1,42 +1,49 @@
|
||||
# Генератор: откуда берутся данные
|
||||
|
||||
Генератор изображает две системы интернет-магазина. Первая — счетчик на сайте,
|
||||
он шлет события в топик `hits`. Вторая — бэкенд магазина, он раз в модельные
|
||||
сутки выгружает слепок заказов в топик `orders`.
|
||||
Генератор имитирует работу двух систем интернет-магазина. Счетчик
|
||||
на сайте отправляет записи о действиях посетителей в топик `hits`. Серверная часть
|
||||
магазина раз в модельные сутки выгружает состояние заказов в топик `orders`.
|
||||
Эта дневная выгрузка называется слепком.
|
||||
|
||||
## Что он производит
|
||||
|
||||
Событие — широкая строка по образцу выгрузки Яндекс Метрики. Генератор создает
|
||||
три вида событий: просмотр страницы, корзину и покупку. Все колонки перечислены
|
||||
Событие содержит сведения о действии посетителя: например, время,
|
||||
адрес страницы и идентификатор посетителя. Формат соответствует образцу
|
||||
выгрузки Яндекс Метрики. Генератор создает три вида событий: просмотр
|
||||
страницы, добавление в корзину и покупку. Все колонки перечислены
|
||||
в [описании выгрузки](../formats/clickstream-event.md).
|
||||
|
||||
Заказ — та же покупка, но записанная бэкендом магазина, с суммами в деньгах.
|
||||
Семь модельных дней после оформления заказ еще может измениться, поэтому каждый
|
||||
дневной слепок несет заказы за последние семь дней в их текущем состоянии.
|
||||
Устройство и форма слепка разобраны в [отдельном
|
||||
Заказ содержит сведения о покупке со стороны магазина: товары, суммы
|
||||
и состояние заказа. После оформления он еще может измениться, например
|
||||
при отмене. Каждый дневной слепок содержит текущее состояние заказов,
|
||||
оформленных за последние семь модельных дней. Состав и формат слепка
|
||||
разобраны в [отдельном
|
||||
справочнике](../architecture/orders/snapshot.md).
|
||||
|
||||
## Почему данные всегда одни и те же
|
||||
|
||||
Генератор не берет случайность извне. Все его случайные решения выводятся из
|
||||
[зерна](../architecture/generator/seeds.md) — одного числа в настройках — и из
|
||||
номера дня. То же зерно и тот же номер дня дают ровно те же события, поэтому
|
||||
стартовый мир одинаков при каждом `make up`.
|
||||
Случайные решения генератора зависят от заданного числа —
|
||||
[зерна генерации](../architecture/generator/seeds.md) — и номера дня.
|
||||
При неизменных настройках и версии генератора одинаковые зерно и день
|
||||
дают одинаковые события. Поэтому при создании стенда вы каждый раз
|
||||
получаете те же начальные данные. Повторный `make up` на работающем стенде
|
||||
сохраняет уже загруженные данные.
|
||||
|
||||
Рядом лежит паспорт мира, `data/world-inventory.json`: зерно, версия генератора
|
||||
и по строке на каждый день с числом событий и контрольной суммой. По нему
|
||||
проверяют, что генератор собрал тот же мир, что и раньше, и что в ODS все
|
||||
доехало без потерь. Паспорт описывает только восемь дней стартового мира.
|
||||
В файле `data/world-inventory.json` записаны зерно, версия генератора,
|
||||
число событий и контрольная сумма за каждый из восьми начальных дней.
|
||||
В документации этот файл называется паспортом мира. С ним можно сверить
|
||||
результат генерации и проверить, все ли события загрузились в ODS.
|
||||
|
||||
## Кто его запускает
|
||||
|
||||
На стенде генератором управляют [даги модельного
|
||||
времени](airflow-dags.md#даги-мира). Его можно запустить и напрямую. Команды
|
||||
собраны в [справочнике мира](../architecture/world.md#как-запустить-генератор).
|
||||
собраны в [справочнике генератора и модельного
|
||||
времени](../architecture/world.md#как-запустить-генератор).
|
||||
|
||||
У генератора два режима. Пакетный отправляет весь день разом. Живой шлет
|
||||
события по ходу модельных суток; сутки идут ускоренно и занимают около двадцати
|
||||
четырех минут.
|
||||
У генератора два режима. Пакетный отправляет все события дня без пауз.
|
||||
В живом режиме события поступают постепенно, как в работающем магазине,
|
||||
но время идет ускоренно: модельные сутки занимают около 24 минут.
|
||||
|
||||
## Посмотрите сами
|
||||
|
||||
@@ -50,13 +57,14 @@ GROUP BY EventDate
|
||||
ORDER BY EventDate;
|
||||
```
|
||||
|
||||
Сравните первые восемь дней с восемью строками в [паспорте
|
||||
мира](../../data/world-inventory.json): числа совпадут. Дни, сыгранные после
|
||||
стартового мира, в паспорте не записаны. Так и задумано.
|
||||
Сравните число событий за каждый из первых восьми дней со значением
|
||||
`events` за ту же дату в [паспорте мира](../../data/world-inventory.json).
|
||||
Числа должны совпасть. Если вы уже генерировали следующие дни,
|
||||
в результате запроса будут дополнительные даты; в паспорте их нет.
|
||||
|
||||
## Куда дальше
|
||||
|
||||
Подробнее генератор разобран в [README папки
|
||||
`generator/`](../../generator/README.md) и в [справочнике его
|
||||
устройства](../architecture/generator/README.md). На этом путеводитель
|
||||
заканчивается: дальше справочники и [учебные задания](../labs/README.md).
|
||||
устройства](../architecture/generator/README.md). Теперь можно переходить
|
||||
к [учебным заданиям](../labs/README.md).
|
||||
+43
-31
@@ -1,52 +1,61 @@
|
||||
# Мониторинг: куда смотреть
|
||||
|
||||
В Grafana три дашборда, и у каждого своя тема. «Данные» показывает, все ли в
|
||||
порядке с потоком данных. «Кластер» — состояние машин и самого ClickHouse.
|
||||
«Запросы» — какие запросы выполнялись и сколько ресурсов они заняли.
|
||||
В Grafana настроены три дашборда. «Данные» показывает загрузку и обработку
|
||||
событий и заказов, «Кластер» — состояние узлов и самого ClickHouse,
|
||||
а «Запросы» — выполненные запросы и затраченные на них ресурсы.
|
||||
|
||||
Prometheus собирает метрики с двух узлов ClickHouse, keeper и экспортера Kafka.
|
||||
Grafana читает и Prometheus, и ClickHouse напрямую. На панелях нет порогов и
|
||||
цветовой подсветки: оценивать картинку придется самому. Автоматические
|
||||
проверки, которые выносят вердикт, собраны в контуре DQ.
|
||||
Prometheus собирает метрики с двух узлов ClickHouse, ClickHouse Keeper
|
||||
и экспортера Kafka — службы, которая предоставляет метрики Kafka.
|
||||
Grafana получает данные из Prometheus и напрямую из ClickHouse.
|
||||
На панелях не заданы пороги для цветовых предупреждений: оценивать показания
|
||||
вы будете самостоятельно. Качество данных автоматически проверяет
|
||||
даг `dq_check`.
|
||||
|
||||
## Дашборд «Данные»
|
||||
|
||||
«Свежесть» показывает, сколько времени прошло с последнего события и с
|
||||
последнего заказа в ODS. Свежесть заказов растет весь модельный день и
|
||||
сбрасывается, когда на границе суток приходит слепок. Это нормальное поведение
|
||||
источника, а не поломка.
|
||||
последнего заказа в ODS. Показатель для заказов растет весь модельный день
|
||||
и снижается, когда поступает очередная дневная выгрузка — слепок.
|
||||
Это ожидаемо: заказы загружаются раз в день.
|
||||
|
||||
«Поток» показывает число сырых сообщений в STG за выбранный интервал. «Брак»
|
||||
рядом — доля строк, которые не удалось разобрать.
|
||||
показывает долю строк, которые не удалось разобрать.
|
||||
|
||||
«Сходимость» сравнивает число событий в Kafka и в ClickHouse. Тревожный
|
||||
признак — устойчивый разрыв между линиями. Расхождение в одном столбце ничего
|
||||
не значит.
|
||||
признак — устойчивый разрыв между рядами. Разовое расхождение еще не говорит
|
||||
о потере данных: метрики Kafka и строки ClickHouse могут попадать в соседние
|
||||
интервалы на графике.
|
||||
|
||||
«Отставание» показывает, сколько сообщений в Kafka еще не прочитано
|
||||
потребителями. «Дневной слепок» перечисляет последние десять слепков заказов в
|
||||
STG: по нему видно, пришла ли выгрузка вовремя.
|
||||
STG: по нему видно, поступила ли очередная выгрузка.
|
||||
|
||||
Источники и правила чтения всех панелей разобраны в [справочнике дашборда
|
||||
«Данные»](../architecture/monitoring/data.md).
|
||||
|
||||
## Почему у панелей разные источники
|
||||
|
||||
Свежесть считается по ODS: если разбор остановился, это видно именно там. Поток
|
||||
и брак считаются по STG, где сохраняется каждое доставленное сообщение. В ODS
|
||||
повторы события и старые версии заказа схлопываются, поэтому счетчик там был бы
|
||||
занижен. Подробности — в [разделе о слоях
|
||||
Свежесть считается по ODS: если новые сообщения перестали разбираться,
|
||||
показатель будет расти. Число поступивших сообщений берется из STG,
|
||||
где сохраняются все сообщения, включая повторы. Для доли брака это число
|
||||
сравнивается с числом строк в таблицах ошибок ODS.
|
||||
|
||||
В основных таблицах ODS повторы событий и старые версии заказов удаляются
|
||||
при слияниях. Поэтому число строк в них не подходит для подсчета
|
||||
всех доставленных сообщений. Подробности — в [разделе о слоях
|
||||
панелей](../architecture/monitoring/data.md#почему-слои-у-панелей-разные).
|
||||
|
||||
## Два других дашборда
|
||||
|
||||
Открывайте «Кластер», когда нужно понять, что происходит с процессором, памятью
|
||||
и дисками, с кусками данных и их слияниями в ClickHouse, с keeper или очередью
|
||||
DDL. Устройство панелей описано в [справочнике дашборда
|
||||
Открывайте «Кластер», чтобы проверить нагрузку на процессор, использование
|
||||
памяти и дисков, число частей таблиц и ход их слияний в ClickHouse. Здесь же
|
||||
показаны состояние ClickHouse Keeper и очередь распределенных DDL-команд.
|
||||
Устройство панелей описано в [справочнике дашборда
|
||||
«Кластер»](../architecture/monitoring/cluster.md).
|
||||
|
||||
«Запросы» пригодится, когда вы ищете тяжелые запросы, ошибки или расход
|
||||
ресурсов по пользователям. Как читать списки, объясняет [справочник дашборда
|
||||
«Запросы» поможет найти медленные запросы, ошибки и пользователей,
|
||||
чьи запросы потребляют много ресурсов. Как читать панели, объясняет
|
||||
[справочник дашборда
|
||||
«Запросы»](../architecture/monitoring/queries.md).
|
||||
|
||||
## Посмотрите сами
|
||||
@@ -57,15 +66,18 @@ Airflow [`world_live_day`](airflow-dags.md#даги-мира): модельны
|
||||
около двадцати четырех минут.
|
||||
|
||||
Смотрите свежесть событий и свежесть заказов по отдельности. Пока день идет,
|
||||
свежесть событий держится на секундах, а свежесть заказов растет. На границе дня
|
||||
слепок отправляется сразу: свежесть заказов сбрасывается, а свежесть событий
|
||||
начинает расти, потому что новых событий до следующего дня не будет. Сам даг
|
||||
остается в работе и после конца дня, потому что ждет дневной конвейер.
|
||||
со времени последнего события проходят секунды, а время с последней
|
||||
загрузки заказов растет. После завершения генерации событий отправляется
|
||||
слепок заказов. Когда он загружен, показатель свежести заказов снижается.
|
||||
Показатель для событий начинает расти: новые события поступят только
|
||||
при генерации следующего дня. Даг пока продолжает работу, ожидая завершения
|
||||
обработки данных в дневном конвейере.
|
||||
|
||||
## Куда дальше
|
||||
|
||||
Состав мониторинга собран в [справочнике
|
||||
зоны](../architecture/monitoring/README.md), детали главного экрана — в
|
||||
[справочнике дашборда «Данные»](../architecture/monitoring/data.md), а границы
|
||||
решения — в [ADR 0002](../adr/0002-monitoring-scope.md). Следующая глава —
|
||||
Устройство мониторинга описано в [техническом
|
||||
справочнике](../architecture/monitoring/README.md), панели дашборда «Данные» —
|
||||
в [отдельном разделе](../architecture/monitoring/data.md).
|
||||
Почему выбраны именно эти показатели, объясняет
|
||||
[ADR 0002](../adr/0002-monitoring-scope.md). Следующая глава —
|
||||
[«Немного Superset»](superset.md).
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
В хранилище приходят два потока из Kafka: в топике `hits` — события
|
||||
кликстрима, в `orders` — заказы магазина. Оба проходят один путь: STG → ODS →
|
||||
DDS → DM. Каждый слой отвечает на свой вопрос.
|
||||
DDS → DM. В STG сообщения сохраняются как есть, в ODS разбираются по полям,
|
||||
в DDS из них собираются события, заказы и сессии, а в DM — витрины для отчетов.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -11,54 +12,54 @@ flowchart LR
|
||||
|
||||
## Как читать имена
|
||||
|
||||
Для обычного чтения выбирайте объекты с суффиксом `_v`. Это представления:
|
||||
их устройство может поменяться, а ваш запрос останется прежним. Суффиксы
|
||||
`_rep`, `_dist`, `_kafka` и `_mv` относятся к внутреннему
|
||||
устройству хранилища. Они нужны для загрузки, обслуживания и диагностики.
|
||||
У словарей есть исключение: у `dic.products` нет суффикса, потому что
|
||||
различать нечего — объект один.
|
||||
Для обычного чтения выбирайте представления с суффиксом `_v`. Они позволяют
|
||||
менять устройство таблиц, сохраняя привычные запросы к данным.
|
||||
Суффиксы `_rep`, `_dist`, `_kafka` и `_mv` относятся к внутреннему устройству
|
||||
хранилища. Эти объекты нужны для загрузки, обслуживания и диагностики.
|
||||
У словаря товаров `dic.products` суффикса нет.
|
||||
Подробный разбор имен есть в [справочнике
|
||||
хранилища](../architecture/storage.md#имена-объектов).
|
||||
|
||||
## STG: как поступило
|
||||
|
||||
STG — сырой слой. Он сохраняет сообщение целой строкой, без разбора. Рядом
|
||||
лежат метаданные доставки: топик, партиция, смещение и время приема. Поэтому в
|
||||
STG можно увидеть, что именно приехало из Kafka, даже если сообщение
|
||||
испорчено.
|
||||
STG — сырой слой. Он сохраняет сообщение целой строкой, без разбора. Вместе
|
||||
с ним записываются сведения о доставке: топик, партиция, смещение и время
|
||||
приема. Содержимое сообщения сохраняется в STG, даже если в нем есть ошибки.
|
||||
|
||||
Срок хранения — трое суток реального времени. Этого хватает для расследования
|
||||
и повторного разбора, но старые строки не занимают диск вечно. Точное правило
|
||||
— в [справочнике
|
||||
Сырые сообщения хранятся трое суток реального времени. В течение этого срока
|
||||
их можно использовать для поиска ошибок и повторной обработки. Затем они
|
||||
удаляются по правилу из [справочника
|
||||
хранилища](../architecture/storage.md#срок-жизни-сырых-данных).
|
||||
|
||||
## ODS: язык источника
|
||||
|
||||
ODS — слой разобранных данных. Строка получает типы: дата становится датой,
|
||||
число — числом. Имена полей остаются на языке источника. Например, событие
|
||||
сохраняет колонки `WatchID`, `ClientID` и `EventDate`.
|
||||
В ODS содержимое сообщения разбирается на колонки с нужными типами данных:
|
||||
датами, числами, строками. Колонки сохраняют имена из источника. Например,
|
||||
в таблице событий есть `WatchID`, `ClientID` и `EventDate`.
|
||||
|
||||
Испорченное сообщение не останавливает загрузку. Оно попадает в таблицу
|
||||
`*_errors` вместе с сырой строкой и классом ошибки. Так брак остается виден, а
|
||||
годные строки продолжают движение.
|
||||
`*_errors` вместе с исходной строкой и классом ошибки. Правильно записанные
|
||||
сообщения обрабатываются дальше.
|
||||
|
||||
## DDS: язык бизнеса
|
||||
|
||||
DDS — детальный слой на языке бизнеса. Здесь есть событие, заказ, сессия и
|
||||
карта идентичностей. Карта связывает посетителя, то есть куку `ClientID`, с
|
||||
пользователем магазина из заказа.
|
||||
DDS — детальный слой: в нем данные подготовлены для анализа событий,
|
||||
заказов и сессий. Здесь же хранится карта идентичностей — таблица связей
|
||||
между идентификатором посетителя `ClientID` и пользователем магазина
|
||||
из заказа. `ClientID` хранится в cookie браузера: по нему можно узнать
|
||||
браузер посетителя, но не всегда самого человека.
|
||||
|
||||
В стенде визитом считают подряд идущие события одной куки без пауз
|
||||
дольше 30 минут. Визит не пересекает границу модельных суток.
|
||||
Аналитик называет такой визит сессией.
|
||||
В стенде визитом, или сессией, считают подряд идущие события одного
|
||||
`ClientID` без пауз дольше 30 минут. Визит не пересекает границу модельных суток.
|
||||
|
||||
В бою Метрика нарезает визиты сама и добавляет готовый `VisitID` в
|
||||
события. Стенд играет ее роль: считает сессии из событий заново, а `VisitID`
|
||||
оставляет эталоном для проверки. Иначе сборка сессий свелась бы к группировке
|
||||
по чужому полю, и учиться было бы не на чем. Идентификатор сессии
|
||||
`session_id` чеканит стенд: в событии его нет. Готовые сессии читайте через
|
||||
`dds.session_v`. В `dds.event_v` поля `VisitID` нет: так сессии можно собрать
|
||||
самому и сравнить с эталоном.
|
||||
Источник передает готовый идентификатор визита `VisitID` по образцу
|
||||
Яндекс Метрики. В учебном хранилище сессии рассчитываются заново по времени
|
||||
событий; каждой присваивается `session_id`. Поле `VisitID` остается
|
||||
эталоном для проверки. Так в заданиях вы сможете самостоятельно определить
|
||||
границы сессий и сравнить их с результатом источника.
|
||||
|
||||
Готовые сессии читайте через `dds.session_v`. События для самостоятельного
|
||||
расчета доступны в `dds.event_v`: в этом представлении `VisitID` скрыт.
|
||||
|
||||
## DM: данные для дашбордов
|
||||
|
||||
@@ -70,32 +71,31 @@ DM — слой витрин. Витрина — готовый набор по
|
||||
путь расчета. Состав готовых витрин смотрите в [карте
|
||||
таблиц](../architecture/storage.md#карта-таблиц).
|
||||
|
||||
## Сбоку цепочки: зона `dic`
|
||||
## Справочные данные: зона `dic`
|
||||
|
||||
Зона `dic` стоит вне пути STG → ODS → DDS → DM. В ней живут справочные данные,
|
||||
которые хранилище получает готовыми. Ни один слой их не производит, а читать
|
||||
может любой.
|
||||
В базе `dic` хранятся готовые справочные данные. Они загружаются отдельно
|
||||
от событий и заказов и могут использоваться в расчетах любого слоя.
|
||||
|
||||
Первый справочник стенда — каталог товаров `dic.products`. Его ключ `sku` —
|
||||
Каталог товаров `dic.products` — один из таких справочников. Его ключ `sku` —
|
||||
артикул товара. По нему можно узнать название, бренд и категорию товара. Как
|
||||
устроена зона, смотрите в [разделе о
|
||||
справочниках](../architecture/storage.md#справочники).
|
||||
|
||||
## Сквозные ключи
|
||||
|
||||
Один и тот же смысл проходит через слои под разными именами: имя меняется
|
||||
вместе с языком слоя. Таблица показывает исходное имя и то, где искать тот же
|
||||
смысл дальше.
|
||||
Идентификаторы позволяют связать данные из разных слоев. При переходе в DDS
|
||||
часть колонок переименовывается: например, `WatchID` становится `event_id`.
|
||||
В таблице указано, как найти соответствующие колонки и соединить по ним данные.
|
||||
|
||||
| Колонка | Что означает | Что соединяет |
|
||||
|---|---|---|
|
||||
| `WatchID` | Идентификатор события | Событие ODS с событием DDS, где колонка называется `event_id` |
|
||||
| `ClientID` | Посетитель, то есть кука | События ODS с событиями, сессиями и картой идентичностей DDS; в DDS колонка называется `client_id` |
|
||||
| `ClientID` | Идентификатор посетителя из cookie браузера | События ODS с событиями, сессиями и картой идентичностей DDS; в DDS колонка называется `client_id` |
|
||||
| `order_id` | Идентификатор заказа | Заказ ODS с заказом DDS и витриной сверки `dm.purchase_vs_orders_v` |
|
||||
| `sku` | Артикул товара в каталоге | Справочник `dic.products` с позициями заказа DDS, где артикулы лежат в `item_sku`; через категорию товара — с витриной выручки DM |
|
||||
| `EventDate` | День на [оси модельного времени](../../CONTEXT.md), который счетчик сайта проставляет в [своем часовом поясе](../architecture/storage.md#часовые-пояса) | Событие ODS с событием DDS, где колонка называется `event_date`, и дневными расчетами DM |
|
||||
| `EventDate` | Дата события в [модельном времени](../../CONTEXT.md), указанная счетчиком сайта в [его часовом поясе](../architecture/storage.md#часовые-пояса) | Событие ODS с событием DDS, где колонка называется `event_date`, и дневными расчетами DM |
|
||||
|
||||
Что здесь значит «посетитель» и чем кука отличается от человека, объясняет
|
||||
Почему идентификатор посетителя не равнозначен человеку, объясняет
|
||||
[словарь понятий](../../CONTEXT.md#язык). Точные имена объектов и полей сверяйте с
|
||||
[картой таблиц](../architecture/storage.md#карта-таблиц).
|
||||
|
||||
@@ -104,10 +104,10 @@ DM — слой витрин. Витрина — готовый набор по
|
||||
Подключитесь к ClickHouse по инструкции из разделов [«Адреса и
|
||||
пароли»](../../README.md#адреса-и-пароли) и [«Подключиться из
|
||||
DBeaver»](../../README.md#подключиться-из-dbeaver). Во всех трех примерах
|
||||
`2026-06-01` — это D0, первый день [стартового
|
||||
мира](../../CONTEXT.md). Чтобы посмотреть другой день, замените
|
||||
эту дату в условии. Первый запрос покажет
|
||||
события одного модельного дня:
|
||||
`2026-06-01` — первый день работы учебного магазина. В документации он
|
||||
обозначается D0; подробнее — в [словаре понятий](../../CONTEXT.md).
|
||||
Чтобы посмотреть другой день, замените дату в условии.
|
||||
Первый запрос покажет 20 событий за выбранный день:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
@@ -122,8 +122,8 @@ ORDER BY UTCEventTime
|
||||
LIMIT 20;
|
||||
```
|
||||
|
||||
Второй запрос покажет сессии того же дня. Они рассчитаны из событий
|
||||
первого запроса:
|
||||
Второй запрос покажет 20 сессий того же дня с наибольшим числом событий.
|
||||
Сессии рассчитаны по всем событиям дня:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
@@ -153,14 +153,13 @@ WHERE report_date = '2026-06-01'
|
||||
ORDER BY revenue DESC;
|
||||
```
|
||||
|
||||
Все три запроса читают поверхности `_v`. Первый показывает данные на языке
|
||||
источника, второй — расчетную сущность, третий — готовый ответ витрины.
|
||||
Все три запроса читают представления `_v`.
|
||||
|
||||
## Куда дальше
|
||||
|
||||
Откройте [интерактивную карту](architecture-map.html) из своей копии
|
||||
репозитория и проследите путь данных.
|
||||
Список объектов, сроки хранения и устройство таблиц — в [справочнике
|
||||
хранилища](../architecture/storage.md). Как данные переносят между слоями — в
|
||||
хранилища](../architecture/storage.md). Как данные обрабатываются между слоями — в
|
||||
следующей главе: [потоки Airflow и даги модельного
|
||||
времени](airflow-dags.md).
|
||||
+26
-21
@@ -6,39 +6,44 @@ Superset показывает витрины слоя DM в виде графи
|
||||
|
||||
| Витрина | Что показывает |
|
||||
|---|---|
|
||||
| `dm.revenue_daily_v` | выручку, заказы и средний чек крупными числами, выручку по дням и категориям столбиками, доли категорий кольцом |
|
||||
| `dm.purchase_vs_orders_v` | сводную сверки: сколько заказов дня попало в каждый класс расхождения |
|
||||
| `dm.daily_traffic_v` | число посетителей крупно, посетителей и известных пользователей по дням, отдельно — долю известных |
|
||||
| `dm.revenue_daily_v` | Выручку, число заказов и средний чек; выручку по дням и категориям товаров, долю каждой категории |
|
||||
| `dm.purchase_vs_orders_v` | Результат сверки покупок из кликстрима с заказами: сколько заказов за день относится к каждому виду расхождения |
|
||||
| `dm.daily_traffic_v` | Число посетителей и известных пользователей по дням, долю известных пользователей |
|
||||
|
||||
Известные пользователи — те, кого удалось связать с посетителями сайта
|
||||
по заказам. Эти связи хранятся в карте идентичностей DDS.
|
||||
|
||||
Слева от панелей стоит фильтр «Период». Он задает даты сразу для всех панелей.
|
||||
|
||||
## Как витрина становится графиком
|
||||
|
||||
От витрины до экрана три объекта Superset: датасет → график → дашборд. Датасет
|
||||
описывает витрину: задает русские имена колонок, формат чисел и показатели —
|
||||
например, средний чек. График ссылается на эти имена и задает способ показа.
|
||||
Дашборд собирает готовые графики на одном экране.
|
||||
В Superset сначала создается датасет — описание таблицы или представления,
|
||||
из которого будут браться данные. В нем задаются подписи колонок, формат
|
||||
чисел и показатели, например средний чек.
|
||||
|
||||
Затем на основе датасета создается график: выбираются показатели и способ
|
||||
их отображения. Несколько графиков можно разместить на одном дашборде.
|
||||
|
||||
## Стендовые объекты и ваши
|
||||
|
||||
Датасеты, графики и дашборд из поставки стенда лежат файлами в репозитории и
|
||||
заново импортируются при каждом `make up`. Если поправить такой объект в
|
||||
интерфейсе, правка проживет до следующего `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#посмотрите-сами). Начальное состояние
|
||||
Последняя дата с выручкой на день раньше последней даты с событиями
|
||||
кликстрима. Выгрузка заказов за день D поступает при генерации следующего
|
||||
дня D+1, а затем обрабатывается конвейером. Вы уже видели эту разницу
|
||||
в [главе об Airflow](airflow-dags.md#посмотрите-сами). Начальное состояние
|
||||
показано в разделе [«Стартовый мир»](../architecture/world.md#стартовый-мир).
|
||||
|
||||
## Посмотрите сами
|
||||
@@ -58,7 +63,7 @@ LIMIT 7;
|
||||
|
||||
## Куда дальше
|
||||
|
||||
Устройство BI-зоны описано в [справочнике
|
||||
Подключение и настройка Superset описаны в [справочнике
|
||||
Superset](../architecture/superset.md), а состав витрин — в [справочнике
|
||||
DM](../architecture/dm.md). Следующая глава — [«Генератор: откуда берутся
|
||||
данные»](generator.md).
|
||||
Reference in new issue
Block a user