Факультативы в отдельной папке #245

Merged
ddmitry merged 4 commits from 244-optional-labs into main 2026-09-07 14:54:11 +03:00
6 changed files with 67 additions and 51 deletions

No files matched your search

+22 -10
View File
@@ -8,15 +8,26 @@
Стенд строится по спеке
[«Боевой реализм стенда (v2)»](docs/specs/2026-07-30-stand-v2-realism.md).
Отсюда вопрос к любой доработке — коду, проверке, документу: **чему на ней
научится менти?** Ответ называется одной фразой до того, как писать. Не
Стенд рассчитан на начинающих инженеров данных. Они недавно изучили ClickHouse,
но почти не работали с ним руками. Здесь они разбирают и достраивают хранилище
небольшого интернет-магазина: проходят путь от загрузки данных до витрин и BI.
Программа дает практику общепринятых инженерных приемов. После нее участники
должны уметь построить похожее хранилище без готового образца. Состав и порядок
работы задает [программа учебных заданий](docs/specs/2026-09-01-labs-program.md).
Стенд существует только ради обучения. Его поддержка имеет смысл, когда
сохраняет возможность пройти программу или сама становится учебной задачей.
Отдельной эксплуатационной ценности у стенда нет.
Отсюда вопрос к любой доработке — коду, проверке, документу: **чему она
учит?** Ответ называется одной фразой до того, как писать. Не
складывается фраза — это вопрос владельцу, а не строчка кода: проверки в этом
репозитории однажды уже переросли продукт.
**Усложнение не бесплатно, и платит за него учебная ценность.** Чем сложнее
стенд, тем хуже он как учебный материал: внимание менти конечно, и каждая
стенд, тем хуже он как учебный материал: внимание читателя конечно, и каждая
конструкция, которую он обязан расшифровать по дороге к уроку, списывается с
этого счёта. Поэтому вопрос выше имеет вторую половину: **что менти платит,
этого счёта. Поэтому вопрос выше имеет вторую половину: **что читатель платит,
чтобы это прочесть, и что получает взамен?** Ответ «вопрос — и ничего»
означает, что писать не нужно.
@@ -157,17 +168,18 @@ Airflow) и названия из кода. Если для понятия ес
дефис (`clickstream-event.md`). Ни даты, ни номера: документ не событие
истории, а текущее описание живого формата — и собирается из кода, а не
пишется руками.
- Имена файлов в `docs/labs/` — `S-N-slug.md`: номер ступени, номер задания
внутри ступени и слаг строчными латинскими буквами через дефис
(`1-2-top-pages-daily.md`), индекс папки — `README.md`. Здесь живут ТЗ
- Имена файлов основной программы в `docs/labs/` — `S-N-slug.md`:
номер ступени, номер задания внутри ступени и слаг строчными латинскими
буквами через дефис (`1-2-top-pages-daily.md`). Здесь живут ТЗ
учебных заданий. Номера повторяют порядок программы из `README.md`, чтобы
папка читалась как оглавление; даты нет: задание — живой документ и
правится вместе с тем, о чем говорит. Слаг называет предмет задания.
Факультативы порядка не имеют и живут под одним слагом
(`superset-dashboard.md`).
Факультативы живут в `docs/labs/optional/`, без номеров, под одним слагом
(`superset-dashboard.md`). Общий индекс обеих частей — `docs/labs/README.md`;
отдельного индекса в `optional/` нет.
- Имена файлов в `docs/handbook/` — слаг строчными латинскими буквами через
дефис, индекс папки — `README.md`. Здесь живет путеводитель по стенду:
учебные главы для менти. Ни дат, ни номеров: глава — живой документ и
учебные главы для читателя. Ни дат, ни номеров: глава — живой документ и
правится вместе с тем, что описывает. Исходники интерактивной карты лежат
подпапкой `architecture-map/`, а ее рендер — файлом `architecture-map.html`
рядом с главами.
+38 -35
View File
@@ -5,24 +5,27 @@
колонок каждой витрины задаёт раздел 7 мастер-спеки; здесь — форма,
наполнение и контроль.
## Форма: по зерну, не по цене запроса
## Таблица или представление
Витрина, меняющая зерно источника — дневной агрегат, сверка по заказам, —
материализуется: `dm.<имя>_rep` / `_dist` и публичное `dm.<имя>_v` с явным
списком колонок, по общим [конвенциям хранилища](storage.md). Наполняет её
`dm_transform`; ритм и механика пересборки — ниже. Витрина, сохраняющая зерно
источника — переименование, обогащение строки, — остаётся обычным
представлением: копию событий ради других имён колонок не держит ни один
боевой склад.
Дневной агрегат и сверка по заказам меняют зерно источника. На этом стенде такие
результаты хранятся в `dm.<имя>_rep` / `_dist` и читаются через публичное
представление `dm.<имя>_v` с явным списком колонок. Имена и устройство объектов
следуют общим [конвенциям хранилища](storage.md). Таблицы наполняет
`dm_transform`; ритм и механика пересборки описаны ниже. В задании этот путь
приходится пройти целиком: рассчитать агрегат, загрузить его и включить
обновление в конвейер.
Правило выбрано учебной целью, а не ценой запроса. На объёмах стенда
представлениями обошлось бы всё: условия сквозь цепочку представлений
проходят ([исследование](../research/2026-08-22-view-predicate-pushdown.md)).
Но пересборка агрегатов конвейером — производственный паттерн, ради
которого стенд и строится, а пара «таблица рядом с представлением»
показывает: форма — решение по роли витрины, у одного слоя законны обе.
Переименование колонок и обогащение строки зерно не меняют. Такие витрины на
стенде остаются обычными представлениями и не хранят вторую копию событий.
## Кто строит: стенд и менти
На объёмах стенда все витрины могли бы остаться представлениями: условия
проходят сквозь их цепочку
([исследование](../research/2026-08-22-view-predicate-pushdown.md)).
Мы все равно оставили материализованные агрегаты ради практики: без них в
программе не было бы загрузки и пересборки витрин. Представления дают другой
случай: преобразование строк на прежнем зерне.
## Что готово в стенде, а что остаётся заданием
Стенд привозит готовыми витрины трёх сюжетов дашборда этапа 8 и
инфраструктуру контроля:
@@ -35,20 +38,20 @@
[картой идентичностей](dds/identity.md);
- `dq_summary` — сводка проверок качества (ниже).
Остальные витрины спеки — учебные задания: менти строит их сам по ТЗ с
образцом. Разминка — представление `events_enriched_v` (зерно события),
затем агрегаты `top_pages_daily`, `session_overview` и `dq_errors_daily`,
последней — самая содержательная `utm_effectiveness` с уроком `declared_*`.
Построенная витрина встаёт в конвейер руками менти: финальный пункт ТЗ
каждого агрегата — добавить задачу своей витрины в `dm_transform`. До этого
конвейер о ней не знает и остаётся зелёным, после — витрина пересобирается
наравне со стендовыми. У разминочного представления такого пункта нет:
пересобирать нечего. Тексты заданий — в [`docs/labs/`](../labs/README.md).
Остальные витрины спеки нужно построить в учебных заданиях по готовому ТЗ и
образцу. Разминка — представление `events_enriched_v` (зерно события), затем
агрегаты `top_pages_daily`, `session_overview` и `dq_errors_daily`, последней —
самая содержательная `utm_effectiveness` с уроком `declared_*`. В финале
каждого задания с агрегатом его задачу нужно добавить в `dm_transform`. До
этого конвейер о витрине не знает, после — пересобирает её вместе со
стендовыми. Представление из разминки добавлять некуда: его не нужно
пересобирать. Тексты заданий лежат в [`docs/labs/`](../labs/README.md).
Дашборд этапа 8 стоит только на витринах стенда: приёмка этапа не зависит
от выполненных домашек. Свой дашборд по витринам менти —
[необязательная лаба](../labs/superset-dashboard.md) после этапа 8. Устройство
стендового дашборда — в [доке зоны Superset](superset.md).
Дашборд этапа 8 читает только готовые витрины стенда, поэтому его приёмка не
зависит от домашних заданий. Отдельный дашборд по учебным витринам можно
собрать в [факультативном задании](../labs/optional/superset-dashboard.md),
доступном после ступени 2. Устройство стендового дашборда описано в
[справочнике Superset](superset.md).
## Ритм пересборки
@@ -215,8 +218,8 @@ business_key`.
## Даг самопроверки
Домашки контролирует `homework_check` — отдельный даг без расписания: менти
запускает его рукой. По задаче на каждое из
Домашние задания проверяет `homework_check` — отдельный даг без расписания,
который запускают вручную. В нём есть задача для каждого из
[пяти заданий по витринам](../labs/README.md).
Задача красная, пока витрины нет или счёт не сходится, и зелёная, когда
построено верно; сообщение об ошибке говорит, что не так и куда смотреть. Проверки — инварианты против источников витрины,
@@ -224,8 +227,8 @@ business_key`.
лабы, а не история качества конвейера.
Приём проверен на соседнем учебном стенде Airflow + Greenplum:
валидационный даг с группами проверок по слоям давал менти обратную связь
по каждому шагу домашки, не трогая рабочий конвейер.
валидационный даг с группами проверок по слоям давал обратную связь по каждому
шагу задания, не трогая рабочий конвейер.
## Отклонённые варианты
@@ -233,7 +236,7 @@ business_key`.
производственный паттерн слоя — пересборка агрегатов — остался бы
невидим, а `dm_transform` — без работы.
- **Материализовать всё.** Копия событий ради переименования колонок —
антипаттерн, который менти увёз бы в бой.
лишняя; такой пример приучал бы без нужды дублировать исходные данные.
- **Гибрид по цене запроса.** Выбор формы по стоимости, которой на объёмах
стенда нет: сторож без настоящей опасности.
- **Проверки домашек в конвейерном звене DQ.** Конвейер стоял бы красным до
@@ -242,8 +245,8 @@ business_key`.
- **«Жёлтый» статус недостроенной витрины.** У задачи Airflow нет такого
состояния; изображать его логами — семантика, которую пришлось бы
расшифровывать. Красное «ещё не построено» честнее.
- **Самопроверка пишет в `dq_summary`.** Попытки менти смешались бы с
историей качества конвейера.
- **Самопроверка пишет в `dq_summary`.** Результаты учебных попыток смешались бы
с историей качества конвейера.
- **Окно заказов для `daily_traffic` — прошлое замерзает.** Дни за окном хранили
бы число известных на момент закрытия — витрина тихо расходится с картой
и протаскивает обратно «знание на дату», отвергнутое развилкой карты
+4 -3
View File
@@ -53,7 +53,7 @@
источнику. Создайте `dm.<имя>_rep` / `_dist`, донор `dm.<имя>_stage_rep` /
`_stage_dist` и публичное `dm.<имя>_v` с явным списком колонок. При прежнем
зерне достаточно представления: таблица дублировала бы данные. Доводы —
раздел «Форма: по зерну, не по цене запроса» [справочника
раздел «Таблица или представление» [справочника
DM](../architecture/dm.md).
**Ключ шардирования — ваше решение.** Объясните, почему выбранный ключ не
@@ -122,8 +122,9 @@ DM](../architecture/dm.md).
### Superset и BI
Открывается после ступени 2. [Свой дашборд в Superset](superset-dashboard.md):
свои объекты BI живут отдельно от стендовых.
Открывается после ступени 2. В задании
[Свой дашборд в Superset](optional/superset-dashboard.md) вы собираете
отдельный дашборд, не меняя объекты стенда.
### Инженерия стенда
@@ -23,7 +23,7 @@
Не добавляйте графики в стендовый дашборд и не правьте его датасеты. При
инициализации Superset импорт с `--overwrite` заменит ручные правки стендовых
объектов файлами из репозитория. `make up` свой дашборд не стирает; срок жизни
таких объектов описан в [доке Superset](../architecture/superset.md), «Импорт
таких объектов описан в [доке Superset](../../architecture/superset.md), «Импорт
при каждой инициализации».
Заведите отдельные датасеты и графики, соберите из них свой дашборд.
+1 -1
View File
@@ -116,7 +116,7 @@
**17. Свой дашборд в Superset (готовая необязательная лаба).**
Урок: пользовательские объекты BI хранятся отдельно от стендовых и переживают перезапуск. Стендовые объекты при импорте перезаписываются.
Материал: `docs/labs/superset-dashboard.md`, `docs/architecture/superset.md`.
Материал: `docs/labs/optional/superset-dashboard.md`, `docs/architecture/superset.md`.\
Форма: построить свое.
Проверка: глазами — счетного инварианта у раскладки панелей нет.
+1 -1
View File
@@ -172,7 +172,7 @@
Открывается после ступени 2 основной программы.
- **Свой дашборд.** Готовая лаба
[`docs/labs/superset-dashboard.md`](../labs/superset-dashboard.md) учит
[`docs/labs/optional/superset-dashboard.md`](../labs/optional/superset-dashboard.md) учит
хранить пользовательские объекты отдельно от стендовых.
- **Почему дашборд не видит объект на второй ноде.** Забытый `ON CLUSTER` может
остаться незаметным до тех пор, пока дашборд не обратится ко второй ноде.