- Зачем:
- README и путеводитель обращаются к читателю на «вы», а ТЗ в docs/labs/
были на «ты»; после пересборки индекса смесь стала заметна.
- Что:
- во всех восьми файлах docs/labs/ местоимения, глаголы и повелительное
наклонение переведены во второе лицо множественного числа.
- названия ступеней в таблице README оставлены как в спеке.
- Проверка:
- grep по формам «ты/твой», 'ё' и 'менти' по docs/labs/ молчит;
git diff --check чистый; ревью диффа свежей сессией.
8.3 KiB
Задание 4: dm.dq_errors_daily
Чему учит: у брака свой день и свой срок жизни. Витрина качества живет по времени загрузки, а не по модельному дню, и переживает собственный источник — поэтому «пересобрать все» здесь означает «стереть историю».
Роль витрины
Сводка приемки: сколько строк за день не прошли разбор и по какой причине. Читают ее, когда качество потока просело: сначала смотрят, вырос ли класс брака, потом идут за сырым текстом в саму таблицу ошибок.
Витрина отвечает на вопрос «сколько и чего», а не «что именно сломалось».
Разбирательство с конкретной строкой начинается в ods.event_errors_dist и
ods.order_errors_dist, где рядом с классом лежат сырой текст и координаты
доставки.
Источник: единственное исключение из правила _v
Общее правило домашек — читать через публичный договор _v. У таблиц брака
такого договора нет, и заводить его ради этой витрины не надо: брак — не
сущность бизнес-модели, а диагностика слоя приема. Читать нужно
распределенные таблицы напрямую:
ods.event_errors_dist— брак разбора событий;ods.order_errors_dist— брак разбора слепка заказов.
Именно _dist, а не _rep: локальная таблица вернет строки одного шарда, и
витрина тихо покажет половину брака. Ошибки при этом не будет — ошибка
появится позже, когда по витрине примут решение.
Зерно и форма
Зерно — день загрузки × источник × класс брака. Зерно источника —
строка брака, значит зерно сменилось и витрина материализуется:
dm.dq_errors_daily_rep / _dist, донор _stage_rep / _stage_dist,
публичное dm.dq_errors_daily_v. Ключ партиции — день загрузки.
День здесь — toDate(_load_ts), то есть настоящее время, когда строка
приехала в хранилище, а не модельный день мира. Модельного дня у брака нет
и быть не может: он живет в содержимом, а содержимое как раз и не
разобралось.
Состав колонок
| Колонка | Тип | Что это |
|---|---|---|
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 — про день,
когда приехал брак, _load_ts — про запуск, который собрал витрину. Первая
деловая, вторая служебная, и совпадать они не обязаны.
Классы у двух источников свои и не пересекаются по смыслу, поэтому колонка
source в зерне обязательна: без нее одинаковое имя класса у событий и у
заказов слилось бы в одну строку.
Ритм пересборки: витрина переживает источник
Таблицы брака живут месяц (TTL), сырые данные — трое суток. Витрина живет без
срока: сводка «сколько брака было в марте» нужна и после того, как сами строки
марта удалены.
Отсюда правило прогона: пересобираются только те дни загрузки, которые
еще есть в источнике. Спросите у источника список живых дней и замените
партиции ровно этих дней. Соблазн «собрать все заново в донор и подменить
таблицу целиком» здесь стоит дороже обычного: истекшие по 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.