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