- Зачем:
- владелец при чтении забраковал прозу ТЗ ступени 1: образы вместо
утверждений, заголовки-метафоры, договоренности стенда поданы как
законы. Тикет #228.
- Что:
- пять ТЗ (задания 1–5) написаны заново по форме ТЗ ступени 2:
содержание, колонки, формулы, самопроверка и приемка сохранены.
- раздел README лаб «Общие правила ступени 1» переименован в «Как принято
на ступени 1» и переписан как выбор с доводом; точечно поправлены
«Самопроверка» и таблица ступени 1.
- Проверка:
- grep по «ё», «менти», формам «ты» и словам-законам по docs/labs/*.md
молчит (единственное «правило» — в нетронутом разделе «Уборка»).
- скрипт ссылок и якорей из #226 печатает пусто; git diff --check чист.
- сверка имен в обратных кавычках и чекбоксов старых и новых файлов —
без расхождений.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
7.5 KiB
Задание 4: dm.dq_errors_daily
Чему учит: считать брак по дню загрузки и сохранять сводку дольше
исходных строк. Пересборка всех партиций после удаления источника по TTL
стирает историю, которую уже не восстановить.
Сначала прочитать
Роль витрины
Сводку открывают при росте брака в потоке: смотрят, каких ошибок стало
больше и сколько строк забраковано. Причину конкретной ошибки исследуют
в ods.event_errors_dist и ods.order_errors_dist, где есть сырой текст и
координаты доставки.
Что сделать
Зерно — день загрузки × источник × класс брака. В источнике зерно —
строка брака. Зерно новое, поэтому витрина хранится готовым агрегатом — см.
«Как принято на ступени 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» и раздел «Раскладка по шардам» справочника хранилища).
Источники: таблицы _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.