From 3bfe9ca4ee6f5711eaf61516330f64b1188616e4 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Sun, 13 Sep 2026 11:20:03 -0400 Subject: [PATCH] =?UTF-8?q?docs(labs):=20=D1=83=D1=82=D0=BE=D1=87=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B0=D0=BC=D0=BE=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20=D0=B8=20=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D0=BC=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B8=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Зачем: убрать механические повторы в итогах и избежать ложных расхождений при проверке графика Superset. Что: уточнены правила итоговых списков и название задания о проверках заказов. В разборе событий разделены учет повторных доставок и выбор событий ODS для сравнения. Первый график Superset и проверочный SQL используют весь период витрины. Проверка: git diff --check, локальные ссылки и переходы к измененным заголовкам прошли. Блоки кода и таблицы требований сохранены. Согласованность периода графика с SQL проверена по тексту; повторный проход через интерфейс Superset не выполнялся. --- docs/labs/1-1-events-enriched.md | 2 +- docs/labs/1-2-top-pages-daily.md | 4 ++-- docs/labs/1-3-session-overview.md | 4 ++-- docs/labs/1-4-dq-errors-daily.md | 6 +++--- docs/labs/1-5-utm-effectiveness.md | 8 ++++---- docs/labs/2-1-superset-chart.md | 18 ++++++++--------- docs/labs/3-1-sessions-by-hand.md | 2 +- docs/labs/4-1-session-pipeline.md | 2 +- docs/labs/5-1-order-checks.md | 4 ++-- docs/labs/5-2-order-parsing.md | 2 +- docs/labs/5-3-order-pipeline.md | 3 +-- docs/labs/6-1-event-parsing.md | 29 ++++++++++++++++----------- docs/labs/7-1-monitoring.md | 2 +- docs/labs/README.md | 2 +- docs/specs/2026-09-01-labs-program.md | 9 +++++---- 15 files changed, 51 insertions(+), 46 deletions(-) diff --git a/docs/labs/1-1-events-enriched.md b/docs/labs/1-1-events-enriched.md index 0a72405..18625a5 100644 --- a/docs/labs/1-1-events-enriched.md +++ b/docs/labs/1-1-events-enriched.md @@ -93,5 +93,5 @@ DDS читают из ODS без отдельной загрузки. Эти с - [ ] у вас есть `dm.events_enriched_v` с явно перечисленными колонками; - [ ] вы сверили число строк и набор `event_id` с `dds.event_v` за каждый прожитый день; расхождений нет; -- [ ] вы запустили `events_enriched` в `homework_check`, проверка успешна; +- [ ] проверка `events_enriched` в `homework_check` прошла успешно; - [ ] витрина работает без физической таблицы и задачи в `dm_transform`. diff --git a/docs/labs/1-2-top-pages-daily.md b/docs/labs/1-2-top-pages-daily.md index b936435..bd1741c 100644 --- a/docs/labs/1-2-top-pages-daily.md +++ b/docs/labs/1-2-top-pages-daily.md @@ -102,9 +102,9 @@ - [ ] у вас есть пять объектов витрины; донор объявлен через `AS` и использует тот же ключ шардирования, что и целевая таблица; -- [ ] вы явно перечислили колонки в `dm.top_pages_daily_v`, включая +- [ ] в `dm.top_pages_daily_v` явно перечислены колонки, включая `_load_id` и `_load_ts`; - [ ] ваш запрос сам определяет дни пересборки по состоянию витрины; -- [ ] вы запустили `top_pages_daily` в `homework_check`, проверка успешна; +- [ ] проверка `top_pages_daily` в `homework_check` прошла успешно; - [ ] вы включили витрину в `dm_transform` и убедились, что повторный прогон конвейера не меняет результат. diff --git a/docs/labs/1-3-session-overview.md b/docs/labs/1-3-session-overview.md index c3ee54f..3e71140 100644 --- a/docs/labs/1-3-session-overview.md +++ b/docs/labs/1-3-session-overview.md @@ -111,5 +111,5 @@ - [ ] вы явно перечислили колонки в `dm.session_overview_v` и собрали показатели из готовых сессий `dds.session_v`; - [ ] в таблице хранятся слагаемые для средних и долей; -- [ ] вы запустили `session_overview` в `homework_check`, проверка успешна; -- [ ] вы включили сборку витрины в `dm_transform`. +- [ ] проверка `session_overview` в `homework_check` прошла успешно; +- [ ] витрина обновляется при запуске `dm_transform`. diff --git a/docs/labs/1-4-dq-errors-daily.md b/docs/labs/1-4-dq-errors-daily.md index ab5c35e..a9506f5 100644 --- a/docs/labs/1-4-dq-errors-daily.md +++ b/docs/labs/1-4-dq-errors-daily.md @@ -103,9 +103,9 @@ - [ ] у вас есть пять объектов витрины; донор объявлен через `AS` и использует ключ шардирования целевой таблицы; -- [ ] вы собираете сводку из таблиц `_dist` для ошибок событий и заказов; +- [ ] сводка включает ошибки событий и заказов из таблиц `_dist`; - [ ] ваш запрос пересобирает только дни, еще доступные в источниках, сохраняя более старые итоги; -- [ ] вы запустили `dq_errors_daily` в `homework_check`, проверка успешна; +- [ ] проверка `dq_errors_daily` в `homework_check` прошла успешно; отсутствие брака тоже дает успешный результат; -- [ ] вы включили сборку витрины в `dm_transform`. +- [ ] витрина обновляется при запуске `dm_transform`. diff --git a/docs/labs/1-5-utm-effectiveness.md b/docs/labs/1-5-utm-effectiveness.md index 4eeb157..e2735ab 100644 --- a/docs/labs/1-5-utm-effectiveness.md +++ b/docs/labs/1-5-utm-effectiveness.md @@ -130,8 +130,8 @@ - [ ] у вас есть пять объектов витрины; донор объявлен через `AS` и использует ключ шардирования целевой таблицы; -- [ ] вы сохранили строки без UTM-меток и используете `Decimal(18, 2)` - для `declared_revenue`; +- [ ] строки без UTM-меток сохранены, а `declared_revenue` хранится + в `Decimal(18, 2)`; - [ ] вы записали, почему сумма отличается от `dm.revenue_daily_v`; -- [ ] вы запустили `utm_effectiveness` в `homework_check`, проверка успешна; -- [ ] вы включили сборку витрины в `dm_transform`. +- [ ] проверка `utm_effectiveness` в `homework_check` прошла успешно; +- [ ] витрина обновляется при запуске `dm_transform`. diff --git a/docs/labs/2-1-superset-chart.md b/docs/labs/2-1-superset-chart.md index 22da07d..fcb68eb 100644 --- a/docs/labs/2-1-superset-chart.md +++ b/docs/labs/2-1-superset-chart.md @@ -45,10 +45,10 @@ укажите «Категория устройства», а «Dimensions» не заполняйте. Дашборд создавать не нужно: сохраненного графика достаточно. -По умолчанию в графике выбран период «No filter». Оставьте его таким или -задайте явные даты. Относительный период, например «Last week», даст пустой -график: модельный календарь стенда отстает от настоящего. Последнюю дату -витрины посмотрите в SQL Lab: +Для этого задания оставьте период «No filter»: график и проверочный запрос +ниже считают долю отказов за весь период витрины. Относительный период, +например «Last week», может дать пустой график: модельный календарь стенда +отстает от настоящего. Последнюю дату витрины посмотрите в SQL Lab: ```sql SELECT max(report_date) @@ -80,12 +80,12 @@ ORDER BY device_category; - [ ] у вас есть физический датасет `dm.session_overview_v` в подключении `ClickHouse`; -- [ ] вы сохранили в нем метрику «Доля отказов» с выражением +- [ ] в датасете есть метрика «Доля отказов» с выражением `SUM(bounce_sessions) / SUM(sessions)` и форматом `.1%`; -- [ ] вы назвали `device_category` и `report_date` по-русски: «Категория +- [ ] колонки `device_category` и `report_date` подписаны «Категория устройства» и «Дата отчета»; -- [ ] у вас сохранен столбиковый график доли отказов по категориям устройств без - относительного фильтра по времени; -- [ ] вы сверили числа на графике с запросом из SQL Lab; +- [ ] сохраненный столбиковый график показывает долю отказов по категориям + устройств за весь период витрины; +- [ ] числа на графике совпадают с результатом запроса из SQL Lab; - [ ] вы сохранили график отдельно, без создания дашборда и изменения стендовых объектов. diff --git a/docs/labs/3-1-sessions-by-hand.md b/docs/labs/3-1-sessions-by-hand.md index 58ca3b8..937b00c 100644 --- a/docs/labs/3-1-sessions-by-hand.md +++ b/docs/labs/3-1-sessions-by-hand.md @@ -89,4 +89,4 @@ ORDER BY EventDate, ClientID; `FULL OUTER JOIN`; - [ ] вы объяснили причину одного расхождения и записали куку, день и два события, на которых оно видно; -- [ ] вы уточнили расчет и получили ноль расхождений во всех днях. +- [ ] уточненный расчет дает ноль расхождений во всех днях. diff --git a/docs/labs/4-1-session-pipeline.md b/docs/labs/4-1-session-pipeline.md index 7671f2c..cb16984 100644 --- a/docs/labs/4-1-session-pipeline.md +++ b/docs/labs/4-1-session-pipeline.md @@ -188,4 +188,4 @@ Distributed-таблицу и такую ошибку не заметит. - [ ] вы получили ноль расхождений в `sessions_vs_reference` за все прожитые дни и вручную сверили границы и атрибуты сессии одной куки; - [ ] ваш запрос с `hostName()` не нашел строк на чужом шарде; -- [ ] вы повторили прогон без удаления данных: он пропустил группу сессий. +- [ ] повторный прогон без удаления данных пропустил группу сессий. diff --git a/docs/labs/5-1-order-checks.md b/docs/labs/5-1-order-checks.md index 48f0c9b..3906d56 100644 --- a/docs/labs/5-1-order-checks.md +++ b/docs/labs/5-1-order-checks.md @@ -1,4 +1,4 @@ -# Проверьте заказы перед изменением обработки +# Научите проверки замечать ошибки в заказах **Чему учит:** написать проверки заказов до изменения их обработки и убедиться на намеренной ошибке, что проверки ее замечают. @@ -139,7 +139,7 @@ ORDER BY check_name; ## Что должно получиться -- [ ] вы включили две новые проверки в `dq_check`; их дневные результаты +- [ ] две новые проверки запускаются в `dq_check`, а их дневные результаты появляются в `dm.dq_summary`; - [ ] вы увидели ошибку каждой проверки после соответствующего изменения заказа, а в журнале нашли примеры заказов с расхождениями; diff --git a/docs/labs/5-2-order-parsing.md b/docs/labs/5-2-order-parsing.md index fb20274..dc61cf8 100644 --- a/docs/labs/5-2-order-parsing.md +++ b/docs/labs/5-2-order-parsing.md @@ -176,5 +176,5 @@ SETTINGS mutations_sync = 2; - [ ] ваш разбор дал тот же результат на новой пробной пачке; - [ ] вы проверили разные значения `created_at` и `updated_at` у годной строки в обоих опытах и подтвердили правильный шард через `hostName()`; -- [ ] вы удалили строки обоих опытов по их маркерам; +- [ ] строки обоих опытов удалены по их маркерам; - [ ] после очистки конвейер и все семь проверок успешны. diff --git a/docs/labs/5-3-order-pipeline.md b/docs/labs/5-3-order-pipeline.md index e45f340..a5d531d 100644 --- a/docs/labs/5-3-order-pipeline.md +++ b/docs/labs/5-3-order-pipeline.md @@ -120,5 +120,4 @@ DROP PARTITION 'YYYY-MM-DD'; с сохраненными значениями; они совпали; - [ ] `order_items_total`, `orders_vs_ods` и пять прежних проверок успешны; - [ ] ваш запрос с `hostName()` не нашел заказов на чужом шарде; -- [ ] вы повторили `etl_pipeline`: деловые данные остались прежними, - проверки прошли. +- [ ] повторный `etl_pipeline` сохранил деловые данные, проверки прошли. diff --git a/docs/labs/6-1-event-parsing.md b/docs/labs/6-1-event-parsing.md index 0fb0027..8c09c92 100644 --- a/docs/labs/6-1-event-parsing.md +++ b/docs/labs/6-1-event-parsing.md @@ -116,6 +116,8 @@ Airflow. При включенном `world_live` посмотрите его т ## Приведите стороны к одному зерну +### Учтите повторные доставки + В STG одна строка представляет доставку. Повтор сообщения остается второй строкой. В `ods.event_v` одна строка представляет актуальное событие, потому что представление читает физическую таблицу с `FINAL`. @@ -124,17 +126,20 @@ Airflow. При включенном `world_live` посмотрите его т полных ключей среди годных доставок. Разница между числом доставок и этим счетом показывает повторы в исходном срезе. -Выберите строки ODS для сравнения независимо от своего условия отбора и -результата вставки. Снова возьмите весь исходный STG-срез. По координатам Kafka -исключите доставки, которые есть в `ods.event_errors_dist`. У оставшихся -доставок извлеките `WatchID` без риска прервать запрос и выберите эти события из свежего -`ods.event_v`. +### Выберите события ODS для сравнения -Свяжите сырую доставку с ODS по `WatchID`: по договору генератора это уникальный -идентификатор события. Здесь он нужен только для выбора событий ODS. -Удаление повторов и последующее соединение используют полный физический ключ. -Не берите список событий из своей таблицы и не применяйте к нему свое условие -отбора. Иначе ошибочно отвергнутая строка исчезнет с обеих сторон сверки. +Теперь нужно найти в ODS события из выбранного среза. Список стройте по +исходным доставкам: если взять его из своей таблицы, ошибочно отвергнутое +событие исчезнет с обеих сторон сверки и потеря останется незамеченной. + +Снова возьмите весь исходный STG-срез. По координатам Kafka исключите +доставки, которые есть в `ods.event_errors_dist`. У оставшихся извлеките +`WatchID` без риска прервать запрос и выберите эти события из свежего +`ods.event_v`. Свое условие отбора здесь не применяйте: решение о годности +доставки вы берете из результата стендового разбора. + +`WatchID` связывает доставку с событием в ODS. Для удаления повторов и +сравнения полей дальше используйте полный физический ключ из схемы таблицы. ## Сверьте 47 полей @@ -198,8 +203,8 @@ Kafka после опыта не нужно. - [ ] у вас сохранены границы выбранного среза, число строк и координаты доставки по партициям Kafka; -- [ ] вы собрали свою таблицу со всеми 47 полями и `_load_ts`, используя - те же правила удаления повторов, что и ODS; +- [ ] ваша таблица содержит все 47 полей и `_load_ts` и обрабатывает + повторы по тем же правилам, что и ODS; - [ ] ваш разбор принимает только JSON-объекты с точным набором ключей и пятью опорными полями, которые преобразуются в нужные типы; - [ ] вы сверили число исходных строк с суммой годных и отвергнутых, diff --git a/docs/labs/7-1-monitoring.md b/docs/labs/7-1-monitoring.md index 4c0ad11..4929a47 100644 --- a/docs/labs/7-1-monitoring.md +++ b/docs/labs/7-1-monitoring.md @@ -101,7 +101,7 @@ ## Что должно получиться -- [ ] вы записали по одному вопросу для каждого из трех дашбордов; +- [ ] для каждого из трех дашбордов записан вопрос, на который он отвечает; - [ ] у вас сохранены окно, текст и показатели верхнего запроса; вы выяснили, кто его отправил и зачем; - [ ] вы нашли запрос открытых дашбордов, который прочитал больше всего diff --git a/docs/labs/README.md b/docs/labs/README.md index 05c69e2..cf593f1 100644 --- a/docs/labs/README.md +++ b/docs/labs/README.md @@ -12,7 +12,7 @@ | 2 | [Свой график в Superset](2-1-superset-chart.md) | превратить свой результат из хранилища в отчет в BI | | 3 | [Нарежьте сессии сами](3-1-sessions-by-hand.md) | сверить число сессий в своей нарезке с эталоном и найти события, из-за которых оно расходится | | 4 | [Перепишите нарезку стенда](4-1-session-pipeline.md) | переписать расчет сессий в готовом конвейере и проверить по исходным событиям | -| 5 | [Проверьте заказы перед изменением обработки](5-1-order-checks.md)
[Перепишите разбор заказов в ODS](5-2-order-parsing.md)
[Перепишите сборку заказов в DDS](5-3-order-pipeline.md) | написать проверки качества до рискованного изменения, затем переписать разбор и сборку заказов | +| 5 | [Научите проверки замечать ошибки в заказах](5-1-order-checks.md)
[Перепишите разбор заказов в ODS](5-2-order-parsing.md)
[Перепишите сборку заказов в DDS](5-3-order-pipeline.md) | написать проверки качества до рискованного изменения, затем переписать разбор и сборку заказов | | 6 | [Разберите сырые события рядом со стендом](6-1-event-parsing.md) | изучить разбор потока отдельно от живого приема и сверить его со стендовым результатом | | 7 | [Мониторинг: куда смотреть](7-1-monitoring.md) | выбрать, куда и на что смотреть в живой системе | diff --git a/docs/specs/2026-09-01-labs-program.md b/docs/specs/2026-09-01-labs-program.md index bec0091..68bc651 100644 --- a/docs/specs/2026-09-01-labs-program.md +++ b/docs/specs/2026-09-01-labs-program.md @@ -51,9 +51,10 @@ с чем сравнить и где искать причину расхождения. Если проверка и есть ход исследования, сохраните ее в шагах, без повторного раздела. В конце задания «Что должно получиться» помогает учащемуся оценить результат: что у него -работает, что он проверил и что может объяснить. Чекбоксы обращены к нему: -«вы сверили числа», «у вас сохранен запрос». Подробный порядок действий -остается в основной части. +работает, что он проверил и что может объяснить. Пишите о наблюдаемом +результате: «числа на графике совпадают с запросом», «вы можете объяснить +причину ошибки». Местоимение «вы» нужно там, где оно помогает обратиться +к читателю. Подробный порядок действий остается в основной части. Заголовки остальных разделов выбирайте по содержанию: «Для чего нужна витрина», «Найдите причину», «Как даг запускает ваши запросы». Число разделов @@ -115,7 +116,7 @@ Форма — вычитание. Обратную связь дают `dq_check` и поштучная сверка, построенная на третьей ступени. -### Ступень 5. Проверьте заказы перед изменением обработки +### Ступень 5. Научите проверки замечать ошибки в заказах Сначала менти строит две недостающие DQ-проверки. Первая утверждает равенство «цена × количество = items_total». Вторая сверяет слой с источником по дням. Их