Files
clickstream-data-platform/docs/labs/5-3-order-pipeline.md
T
ddadmin 596bcba01e docs(labs): разделено задание по заказам на три шага
- Зачем:
  - одно длинное ТЗ заставляло одновременно держать в голове три самостоятельных опыта и их очистку.
- Что:
  - проверки, разбор ODS и сборка DDS разнесены по трем последовательным заданиям.
  - уточнены границы учебной реализации, место диагностики и выбор закрытого дня.
  - оглавление ступени 5 дополнено ссылками на все три задания.
- Проверка:
  - проверены ссылки, пробная пачка jq, кластерные мутации и отсутствие ошибок пробелов в diff.
2026-09-06 16:25:04 -04:00

125 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Перепишите сборку заказов в DDS
**Чему учит:** переписать пересборку заказов по состоянию слоев и доказать ее
результат на пропущенном закрытом дне.
## Сначала прочитать
- [проверки заказов](5-1-order-checks.md);
- [разбор заказов в ODS](5-2-order-parsing.md);
- [модель заказа DDS](../architecture/dds/order.md);
- [дневной конвейер](../architecture/etl.md#объём-прогона);
- [раскладку по шардам](../architecture/storage.md#раскладка-по-шардам).
## Граница задания
Удалите готовый SQL и перепишите только три файла:
- `sql/dds/order_scope.sql`;
- `sql/dds/order_rebuild.sql`;
- `sql/dds/order_replace.sql`.
Даг `dds_transform`, DDL, донор, ODS и обе проверки из первого задания уже
задают границу работы. Перед началом убедитесь, что пробные строки предыдущего
задания удалены, а семь DQ дают зеленый результат.
Поставьте `world_live` на паузу и дождитесь завершения активных прогонов. До
завершения опыта не запускайте `world_live_day`, `world_initialize` и
`world_recreate`. `world_next_day` понадобится только в явно указанном ниже
случае.
## Договор с дагом
Сохраните интерфейс `dds_transform`:
| Файл | Вход | Результат |
|---|---|---|
| `order_scope.sql` | без параметров | одна строка `first_day`, `last_day` |
| `order_rebuild.sql` | `{first_day:Date}`, `{last_day:Date}`, `{load_id:String}` | выбранные дни в `dds.order_stage_dist` |
| `order_replace.sql` | день в `{{ params.day }}` | партиция дня в `dds.order_rep` |
Объем состоит из текущего окна источника и хвоста от первого дня, который есть
в ODS, но отсутствует в DDS. Текущее окно дают строки последнего
`snapshot_date`: их минимальный и максимальный день заказа. Если источник
пуст, `order_scope.sql` не возвращает строку. Если дыр нет, `first_day` равен
началу окна. Если дыра старше, непрерывный отрезок начинается с нее.
`order_rebuild.sql` сначала очищает все партиции `dds.order_stage_rep` на
кластере, затем записывает в `dds.order_stage_dist` весь выбранный отрезок. Он
читает текущее состояние `ods.order_v`, вычисляет `order_date`, переводит
времена в `Europe/Samara`, разбирает `items` в три параллельных массива и
ставит координаты запуска.
Запись через Distributed должна завершиться до замены и использовать ключ
целевой таблицы для раскладки строк. Способ собрать весь отрезок внутри файла
выберите сами.
`order_replace.sql` работает с локальными `dds.order_rep` и
`dds.order_stage_rep` на всем кластере. `REPLACE PARTITION` переносит готовую
дневную партицию из донора и оставляет донор на месте. Структура, ключи и
политика хранения совпадают: DDL объявляет донор через `AS dds.order_rep`.
## Восстановите ближайший закрытый день
Найдите последний по дате день DDS, который лежит левее начала текущего окна
ODS. Это ближайший к окну закрытый день: его удаление показывает расширение
объема на дыру без пересборки всей истории.
Если такого дня еще нет, один раз продвиньте мир через `world_next_day`,
дождитесь `orders_ingest`, затем запустите `etl_pipeline`. После этого снова
зафиксируйте модельное время до конца опыта и выберите ближайший закрытый день.
Сохраните для него число заказов и контрольную сумму деловых полей без
`_load_id` и `_load_ts`. Удалите только его партицию:
```sql
ALTER TABLE dds.order_rep ON CLUSTER clickstream_cluster
DROP PARTITION 'YYYY-MM-DD';
```
Сразу запустите `dq_check`, до восстановления партиции. Красный результат
должны дать `orders_vs_ods` и `purchase_vs_orders_vs_dds`.
`revenue_daily_vs_dds` тоже даст красный результат, если в партиции были
оплаченные заказы. `classes_vs_inventory` останется зеленым: до запуска
`dm_transform` эта проверка читает прежнюю витрину сверки.
Запустите `etl_pipeline`. В группе `dds_transform.order` значение `first_day`
должно совпасть с удаленным днем, а задачи `replace` - покрыть непрерывный
отрезок от него до конца текущего окна. `first_day` ищите в строке про объем
пересборки в журнале задачи `order.scope` дага `dds_transform`. После успешного
прогона число заказов и контрольная сумма выбранного дня должны совпасть с
сохраненными.
## Проверьте раскладку и повтор
Напишите отдельный запрос к `dds.order_dist`, который получает фактическую
ноду через `hostName()`, вычисляет ожидаемую по `cityHash64(order_id) % 2` и
считает несовпадения по каждой ноде. Остаток 0 соответствует
`clickhouse-01`, остаток 1 - `clickhouse-02`. На обеих нодах число строк на
чужом шарде должно быть нулевым. Счетные DQ читают Distributed-таблицы и такую
ошибку раскладки не обнаруживают.
Запустите `etl_pipeline` еще раз при неизменном модельном времени. Группа
заказов снова должна пересобрать текущее изменяемое окно. Контрольные суммы
деловых полей остаются прежними, а все семь проверок дают зеленый результат.
## Когда можно остановиться
Удаленная партиция восстановлена, ее число строк и контрольная сумма совпали
с исходными. На чужих шардах строк нет, повторный прогон не изменил деловые
данные, семь DQ зелены. Если до упражнения `world_live` работал, теперь его
можно снять с паузы.
## Приемка
- [ ] переписаны только три файла `sql/dds/order_*.sql`, инфраструктура
упражнения не изменена;
- [ ] удален ближайший к окну закрытый день, а красный DQ зафиксирован до
восстановления;
- [ ] `first_day` начался с удаленного дня, задачи замены покрыли непрерывный
отрезок до конца окна;
- [ ] число заказов и контрольная сумма восстановленного дня совпали;
- [ ] `order_items_total`, `orders_vs_ods` и пять прежних DQ зелены;
- [ ] проверка `hostName()` не нашла заказов DDS на чужом шарде;
- [ ] повторный `etl_pipeline` сохранил деловые данные и зеленые проверки.