Зачем: помочь менти понять действия, проверить результат и оценить освоенное умение. Что: вычитаны 13 заданий основной программы и общий индекс. Итоговые списки обращены к учащемуся, убраны история разработки и повторы. Правила учебного текста записаны в программе, из AGENTS.md добавлена ссылка. Проверка: git diff --check, локальные ссылки и ссылки на измененные заголовки прошли. Блоки кода и таблицы требований совпадают с исходными. Упражнения на стенде повторно не выполнялись: изменен только текст.
112 lines
7.2 KiB
Markdown
112 lines
7.2 KiB
Markdown
# Задание 4: `dm.dq_errors_daily`
|
|
|
|
**Чему учит:** считать брак по дню загрузки и сохранять сводку дольше
|
|
исходных строк.
|
|
|
|
## Сначала прочитать
|
|
|
|
- [«Хранилище и его слои»](../handbook/storage-layers.md);
|
|
- [«Потоки Airflow и даги модельного времени»](../handbook/airflow-dags.md).
|
|
|
|
## Для чего нужна витрина
|
|
|
|
Сводку открывают при росте брака в потоке: смотрят, каких ошибок стало
|
|
больше и сколько строк забраковано. Причину конкретной ошибки исследуют
|
|
в `ods.event_errors_dist` и `ods.order_errors_dist`, где есть сырой текст и
|
|
координаты доставки.
|
|
|
|
## Что сделать
|
|
|
|
Зерно — **день загрузки × источник × класс брака**. В источнике зерно —
|
|
строка брака. Зерно новое, поэтому витрина хранится готовым агрегатом — см.
|
|
[«Как принято на ступени 1»](README.md#как-принято-на-ступени-1). Создайте
|
|
пять объектов: `dm.dq_errors_daily_rep` / `_dist`, донор `_stage_rep` /
|
|
`_stage_dist` и публичное представление `dm.dq_errors_daily_v`. Ключ
|
|
партиции — день загрузки.
|
|
|
|
### Состав колонок
|
|
|
|
| Колонка | Тип | Значение |
|
|
|---|---|---|
|
|
| `load_date` | `Date` | День загрузки забракованной строки |
|
|
| `source` | `LowCardinality(String)` | `event` или `order` |
|
|
| `error_class` | `LowCardinality(String)` | Класс брака из таблицы ошибок |
|
|
| `error_rows` | `UInt64` | Число забракованных строк |
|
|
| `_load_id` | `String` | Идентификатор запуска, собравшего день |
|
|
| `_load_ts` | `DateTime64(3, 'UTC')` | Время сборки |
|
|
|
|
Вычислите `load_date` как `toDate(_load_ts)` из таблицы ошибок — это
|
|
реальный день приема строки. Модельный день записан внутри исходной строки.
|
|
Ее не удалось разобрать, поэтому надежно получить из нее день не получится.
|
|
Служебная `_load_ts` витрины описывает сборку сводки; ее дата может
|
|
отличаться от `load_date`.
|
|
|
|
У событий и заказов свои классы брака. `source` входит в зерно, чтобы
|
|
одинаковые имена классов с разным смыслом не объединялись в одну строку.
|
|
|
|
### Ритм пересборки
|
|
|
|
Брак хранится месяц по `TTL`, сырые данные — трое суток. Сводка хранится
|
|
бессрочно: итоги нужны и после удаления исходных строк.
|
|
|
|
Получите список дней загрузки, еще имеющихся в источниках. Соберите их в
|
|
донор и замените только эти партиции, сохранив остальные.
|
|
|
|
В течение текущих суток ошибки еще поступают: пересчитайте этот день на
|
|
следующем прогоне.
|
|
|
|
### Ключ шардирования
|
|
|
|
Выберите ключ самостоятельно. Классов брака у событий и заказов вместе
|
|
меньше десятка. Объясните, насколько существенен перекос при таком объеме.
|
|
|
|
Ключ донора — тот же, что у цели (см. [«Как принято на ступени
|
|
1»](README.md#как-принято-на-ступени-1) и раздел «Раскладка по шардам»
|
|
[справочника хранилища](../architecture/storage.md)).
|
|
|
|
## Источники: таблицы `_dist`
|
|
|
|
Только это задание читает данные не через `_v`: брак нужен для диагностики
|
|
приема и не входит в бизнес-модель. Публичных представлений у таблиц ошибок
|
|
нет, создавать их для задания не нужно. Источники:
|
|
|
|
- `ods.event_errors_dist` — ошибки разбора событий;
|
|
- `ods.order_errors_dist` — ошибки разбора слепка заказов.
|
|
|
|
Чтение локальной `_rep` даст строки одного шарда из двух: часть брака не
|
|
попадет в сводку, хотя запрос выполнится без ошибки.
|
|
|
|
## Типичная ошибка
|
|
|
|
Если заменить всю таблицу данными из нового донора, исчезнут итоги дней,
|
|
истекших по `TTL` источника. Восстановить их неоткуда.
|
|
|
|
## Как проверить себя
|
|
|
|
Деловой ключ — `source` и `error_class` внутри `load_date`. Проверяйте дни,
|
|
оставшиеся хотя бы в одной таблице ошибок. Если дня за пределами `TTL` уже
|
|
нет в источнике, это не ошибка: сверять его уже не с чем.
|
|
|
|
Посчитайте строки прямо в обеих таблицах ошибок и соедините результат с
|
|
`dm.dq_errors_daily_v` полным внешним соединением по ключу. Затем посчитайте
|
|
строки, где ключ отсутствует с одной из сторон или различается `error_rows`.
|
|
Расхождений должно быть ноль.
|
|
|
|
Сумма `error_rows` по проверяемым дням равна общему числу строк в
|
|
`ods.event_errors_dist` и `ods.order_errors_dist`. Если она примерно вдвое
|
|
меньше, вероятная причина — чтение `_rep` вместо `_dist`.
|
|
|
|
Если в источниках нет брака, витрина должна быть пустой. В этом случае
|
|
расхождений тоже ноль и проверка успешна.
|
|
|
|
## Что должно получиться
|
|
|
|
- [ ] у вас есть пять объектов витрины; донор объявлен через `AS` и
|
|
использует ключ шардирования целевой таблицы;
|
|
- [ ] вы собираете сводку из таблиц `_dist` для ошибок событий и заказов;
|
|
- [ ] ваш запрос пересобирает только дни, еще доступные в источниках,
|
|
сохраняя более старые итоги;
|
|
- [ ] вы запустили `dq_errors_daily` в `homework_check`, проверка успешна;
|
|
отсутствие брака тоже дает успешный результат;
|
|
- [ ] вы включили сборку витрины в `dm_transform`.
|