docs(labs): упрощен язык учебных заданий
- Зачем: начинающим трудно читать задания из-за необъясненных терминов и неестественных формулировок. - Что: переработаны вводная и 21 задание, названы темы разделов, объяснены термины и сокращены повторы; согласованы правила учебного текста и ссылки. - Проверка: сохранены 25 блоков SQL и команд и таблицы состава колонок; проверены 153 локальные ссылки и 32 входящие ссылки на разделы; git diff --check прошел.
This commit is contained in:
1 parent
3c3eb825e1
commit
4693bc5af9
24 files changed
+782
-684
No files matched your search
@@ -1,9 +1,10 @@
|
||||
# Перепишите разбор заказов в ODS
|
||||
# Разбор заказов в ODS
|
||||
|
||||
**Чему учит:** переписать разбор заказов и на пробных сообщениях проверить,
|
||||
что годные строки и брак попадают в свои таблицы без потерь.
|
||||
Вы перепишете разбор заказов в ODS. На четырех пробных сообщениях проверите,
|
||||
что правильно заполненный заказ и сообщения с ошибками попадают
|
||||
в соответствующие таблицы без потерь.
|
||||
|
||||
## Сначала прочитать
|
||||
## Подготовка
|
||||
|
||||
- [проверки заказов](5-1-order-checks.md);
|
||||
- [прием заказов в ODS](../architecture/orders/ingestion.md);
|
||||
@@ -11,24 +12,22 @@
|
||||
- [`orders_ingest`](../../dags/orders_ingest.py);
|
||||
- [`order_parse.sql`](../../sql/ods/order_parse.sql).
|
||||
|
||||
Запрос для проверки пробных строк вы напишете сами.
|
||||
|
||||
## Что предстоит сделать
|
||||
## Порядок работы
|
||||
|
||||
Сначала проведите опыт на готовом `order_parse.sql`. Затем удалите его SQL,
|
||||
соберите разбор заново и повторите опыт с другим маркером.
|
||||
|
||||
Не меняйте устройство `orders_ingest`, DDL, Kafka, таблиц и преобразований
|
||||
DDS. Оба опыта должны закончиться адресной очисткой только своих строк.
|
||||
Сохраните устройство `orders_ingest`, DDL, Kafka, таблиц и преобразований
|
||||
DDS. После каждого опыта удалите только добавленные вами строки.
|
||||
|
||||
Перед началом убедитесь, что после [предыдущего задания](5-1-order-checks.md)
|
||||
все семь DQ остались зелеными. Поставьте `world_live` на паузу, дождитесь
|
||||
все семь проверок качества прошли успешно. Поставьте `world_live` на паузу, дождитесь
|
||||
активных прогонов и до завершения опыта не запускайте `world_next_day`,
|
||||
`world_live_day`, `world_initialize` и `world_recreate`. Не запускайте
|
||||
`etl_pipeline` между
|
||||
отправкой пробной пачки и ее очисткой.
|
||||
|
||||
## Четыре строки для двух ветвей
|
||||
## Пробные сообщения
|
||||
|
||||
Сделайте четыре сообщения с общим уникальным маркером:
|
||||
|
||||
@@ -39,9 +38,9 @@ DDS. Оба опыта должны закончиться адресной оч
|
||||
`field_invalid`.
|
||||
|
||||
`not_an_object` означает, что корень JSON не объект. `keyset_mismatch` означает,
|
||||
что у объекта отличается точный набор верхнеуровневых ключей. `field_invalid`
|
||||
означает, что ключи на месте, но значение не прошло проверку типа, формата или
|
||||
вместимости.
|
||||
что у объекта есть лишние верхнеуровневые ключи или не хватает обязательных.
|
||||
`field_invalid` означает, что ключи на месте, но значение имеет неверный тип,
|
||||
формат или не помещается в заданный тип данных.
|
||||
|
||||
Соберите строки в `/tmp/<маркер>.jsonl`. Заготовка дает одну годную строку и
|
||||
по одному примеру каждого класса брака:
|
||||
@@ -79,31 +78,33 @@ docker compose exec -T kafka /opt/kafka/bin/kafka-console-producer.sh \
|
||||
--bootstrap-server kafka:9092 --topic orders < "$LAB_BATCH"
|
||||
```
|
||||
|
||||
Запустите `orders_ingest` и найдите `_load_id` по маркеру в
|
||||
`stg.orders_raw_dist`. У четырех строк должен быть один идентификатор прогона.
|
||||
Запустите `orders_ingest`. Найдите свои строки по маркеру в
|
||||
`stg.orders_raw_dist` и сохраните их `_load_id`: это идентификатор запуска,
|
||||
который принял сообщения. Он должен быть одинаковым у всех четырех строк.
|
||||
|
||||
## Зафиксируйте исходный результат
|
||||
## Проверка готового разбора
|
||||
|
||||
До любого запуска `etl_pipeline` проверьте срез по найденному `_load_id`:
|
||||
До запуска `etl_pipeline` проверьте строки с найденным `_load_id`:
|
||||
|
||||
- в STG четыре строки;
|
||||
- в физической `ods.order_dist` одна годная строка;
|
||||
- в таблице `ods.order_dist` одна годная строка;
|
||||
- в `ods.order_errors_dist` три строки, по одной каждого класса;
|
||||
- `STG = годные + брак`;
|
||||
- текущая строка `ods.order_v` совпадает по деловым полям с результатом
|
||||
`argMax` по `snapshot_date` из годного сырья среза.
|
||||
- поля заказа в текущей строке `ods.order_v` совпадают с полями из годного
|
||||
исходного сообщения; последнюю версию для сравнения выберите через
|
||||
`argMax` по `snapshot_date`.
|
||||
|
||||
Счет физической таблицы нужен именно по `_load_id`: представление
|
||||
`ods.order_v` оставляет текущую версию сущности и не показывает, сколько строк
|
||||
разобрал запуск. Запрос сверки с `argMax` напишите сами. Эталонные деловые поля
|
||||
стройте только из `raw`; отдельно сравните различающиеся `created_at` и
|
||||
`updated_at`.
|
||||
Считайте строки `ods.order_dist` именно по `_load_id`: представление
|
||||
`ods.order_v` оставляет только текущую версию каждого заказа и не показывает,
|
||||
сколько строк разобрал запуск. Запрос сверки с `argMax` напишите сами.
|
||||
Значения для сравнения извлеките из `raw` пробных сообщений. Отдельно
|
||||
сравните `created_at` и `updated_at`: в заготовке они намеренно различаются.
|
||||
|
||||
Проверьте раскладку годной строки через `hostName()` на `ods.order_dist`.
|
||||
Фактическая нода должна совпасть с остатком `cityHash64(order_id) % 2`:
|
||||
Узел, на котором лежит строка, должен соответствовать остатку `cityHash64(order_id) % 2`:
|
||||
0 - `clickhouse-01`, 1 - `clickhouse-02`.
|
||||
|
||||
## Уберите пробную пачку
|
||||
## Удаление пробных сообщений
|
||||
|
||||
Удалите только строки маркера из локальных таблиц:
|
||||
|
||||
@@ -135,40 +136,41 @@ SETTINGS mutations_sync = 2;
|
||||
запустите `etl_pipeline`: пересборка текущего окна удалит заказ из DDS и
|
||||
обновит витрины.
|
||||
|
||||
## Перепишите разбор
|
||||
## Собственный разбор заказов
|
||||
|
||||
Удалите готовый SQL из `sql/ods/order_parse.sql` и напишите свой. Чтобы
|
||||
`orders_ingest` мог его использовать, сохраните следующие условия:
|
||||
|
||||
- вход - строки `stg.orders_raw_dist` одного `{load_id:String}`;
|
||||
- каждая строка среза попадает ровно в один результат: годный заказ или брак;
|
||||
- произвольный `raw` не останавливает весь разбор исключением;
|
||||
- запрос читает строки `stg.orders_raw_dist` с переданным `{load_id:String}`;
|
||||
- каждая прочитанная строка попадает ровно в один результат: годный заказ или брак;
|
||||
- ошибка в `raw` одной строки не прерывает разбор остальных;
|
||||
- годные строки записываются в `ods.order_dist`, остальные - в
|
||||
`ods.order_errors_dist`;
|
||||
- классы брака и их порядок - `not_an_object`, `keyset_mismatch`,
|
||||
`field_invalid`;
|
||||
- метки доставки и `_load_id` переходят из STG без пересчета;
|
||||
- задача завершается после доставки обоих результатов через Distributed, а
|
||||
строки распределяются по ключу целевой таблицы.
|
||||
- задача завершается после записи и заказов, и ошибок на шарды через
|
||||
Distributed; строки распределяются по ключу соответствующей целевой таблицы.
|
||||
|
||||
Точный набор полей, типы и граница строгого приема описаны в
|
||||
Точный набор полей, типы и условия проверки значений описаны в
|
||||
[документе приема](../architecture/orders/ingestion.md#граница-строгого-приёма),
|
||||
а целевые колонки - в [`20-ods-tables.sql`](../../sql/ddl/20-ods-tables.sql).
|
||||
Внутренность `items` остается сырым JSON: ее разбирает DDS.
|
||||
Содержимое `items` сохраните как JSON: его разбирает DDS.
|
||||
|
||||
Повторите опыт с новым маркером. Получите тот же баланс 4 = 1 + 3, те же три
|
||||
класса, верную текущую строку по `snapshot_date`, разные времена и правильный
|
||||
шард. Затем очистите второй срез теми же адресными командами и запустите
|
||||
класса, верную текущую версию заказа по `snapshot_date`, разные значения
|
||||
`created_at` и `updated_at` и правильный шард. Затем удалите строки второго
|
||||
опыта теми же командами и запустите
|
||||
`dq_check`.
|
||||
|
||||
## Завершите опыт
|
||||
## Завершение работы
|
||||
|
||||
Убедитесь, что оба маркера отсутствуют в STG, ODS, таблице брака и DDS,
|
||||
временные файлы удалены, а семь проверок успешны. Теперь можно перейти к
|
||||
сборке DDS, не снимая паузу с модельного времени. Если вы прерываетесь и до
|
||||
опыта `world_live` работал, снимите его с паузы.
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
- [ ] у вас сохранены результаты до переписывания: четыре строки дали
|
||||
один заказ и три класса брака; вы сверили поля текущей версии и шард;
|
||||
|
||||
Reference in new issue
Block a user