Зачем: начинающим ученикам трудно читать главы без пояснений терминов и ожидаемого результата примеров. Что: уточнены заголовки и объяснения в пяти главах и вводной, добавлена сверка графика с SQL, обновлены ссылки из заданий и документации генератора. Проверка: SQL и команды сохранены, локальные ссылки проверены; git diff --check пройден. Ревью смысла Sol 6.1 high замечаний не выявило, новые пояснения дополнительно сверены с кодом и настройками.
114 lines
7.6 KiB
Markdown
114 lines
7.6 KiB
Markdown
# Задание 4: ошибки загрузки по дням, `dm.dq_errors_daily`
|
||
|
||
Вы соберете дневную сводку ошибок загрузки. Ее итоги должны сохраниться
|
||
и после того, как исходные сообщения будут удалены из хранилища.
|
||
|
||
## Подготовка
|
||
|
||
- [«Хранилище и его слои»](../handbook/storage-layers.md);
|
||
- [«Генерация и обработка данных в Airflow»](../handbook/airflow-dags.md).
|
||
|
||
## Ошибки загрузки и их источники
|
||
|
||
Если сообщение не удалось разобрать, стенд записывает его в таблицу ошибок.
|
||
Такие строки дальше называются браком. Вы соберете сводку, по которой можно
|
||
увидеть, каких ошибок стало больше и сколько строк забраковано.
|
||
|
||
Источники сводки:
|
||
|
||
- `ods.event_errors_dist`: ошибки разбора событий;
|
||
- `ods.order_errors_dist`: ошибки разбора выгрузки заказов.
|
||
|
||
В этих таблицах есть исходный текст сообщения и сведения о его доставке:
|
||
они пригодятся при поиске причины ошибки. Представлений `_v` у таблиц ошибок
|
||
нет, создавать их для задания не нужно. Чтение локальной таблицы `_rep`
|
||
даст строки только одного шарда из двух, поэтому используйте `_dist`.
|
||
|
||
## Создание сводки
|
||
|
||
В результате нужна одна строка на день загрузки, источник и класс ошибки.
|
||
Например, ошибки `field_invalid` в заказах за один день загрузки попадут
|
||
в одну строку с их количеством.
|
||
|
||
Создайте пять объектов по [общим правилам ступени 1](README.md#создание-и-обновление-витрин):
|
||
|
||
- основные таблицы `dm.dq_errors_daily_rep` и `dm.dq_errors_daily_dist`;
|
||
- промежуточные таблицы `dm.dq_errors_daily_stage_rep` и `dm.dq_errors_daily_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#создание-и-обновление-витрин).
|
||
|
||
## Типичная ошибка
|
||
|
||
Если заменить всю сводку новым расчетом, исчезнут итоги дней, за которые
|
||
исходные строки уже удалены по `TTL`. Восстановить эти итоги неоткуда.
|
||
|
||
## Проверка результата
|
||
|
||
Сопоставляйте строки по `load_date`, `source` и `error_class`. Проверяйте дни,
|
||
оставшиеся хотя бы в одной таблице ошибок. Старые итоги, для которых исходные
|
||
строки уже удалены по `TTL`, сверять не с чем.
|
||
|
||
Посчитайте строки прямо в обеих таблицах ошибок и соедините результат с
|
||
`dm.dq_errors_daily_v` через `FULL OUTER JOIN` по этим трем полям. Посчитайте
|
||
строки, которые есть только с одной стороны или у которых различается `error_rows`.
|
||
Расхождений должно быть ноль.
|
||
|
||
Сумма `error_rows` по проверяемым дням равна общему числу строк в
|
||
`ods.event_errors_dist` и `ods.order_errors_dist`. Если она примерно вдвое
|
||
меньше, вероятная причина — чтение `_rep` вместо `_dist`.
|
||
|
||
Если в источниках нет брака, витрина должна быть пустой. В этом случае
|
||
расхождений тоже ноль и проверка успешна.
|
||
|
||
## Результат работы
|
||
|
||
- [ ] у вас есть пять объектов витрины; промежуточная таблица объявлена через
|
||
`AS` и использует ключ шардирования основной;
|
||
- [ ] сводка включает ошибки событий и заказов из таблиц `_dist`;
|
||
- [ ] ваш запрос пересобирает только дни, еще доступные в источниках,
|
||
сохраняя более старые итоги;
|
||
- [ ] проверка `dq_errors_daily` в `homework_check` прошла успешно;
|
||
отсутствие брака тоже дает успешный результат;
|
||
- [ ] витрина обновляется при запуске `dm_transform`.
|