Files
clickstream-data-platform/docs/labs/5-3-order-pipeline.md
T
ddadmin 3bfe9ca4ee docs(labs): уточнены самопроверка и формулировки заданий
Зачем: убрать механические повторы в итогах и избежать ложных расхождений при проверке графика Superset.

Что: уточнены правила итоговых списков и название задания о проверках заказов. В разборе событий разделены учет повторных доставок и выбор событий ODS для сравнения. Первый график Superset и проверочный SQL используют весь период витрины.

Проверка: git diff --check, локальные ссылки и переходы к измененным заголовкам прошли. Блоки кода и таблицы требований сохранены. Согласованность периода графика с SQL проверена по тексту; повторный проход через интерфейс Superset не выполнялся.
2026-09-13 11:20:03 -04:00

8.5 KiB
Raw Blame History

Перепишите сборку заказов в DDS

Чему учит: настроить пересборку заказов по состоянию ODS и DDS и проверить, что она восстанавливает пропущенный день за пределами текущего окна.

Сначала прочитать

Что предстоит сделать

Удалите готовый 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. Удалите только его партицию:

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 еще раз при неизменном модельном времени. Группа заказов снова должна пересобрать текущее изменяемое окно. Контрольные суммы деловых полей остаются прежними, а все семь проверок дают зеленый результат.

Завершите опыт

После восстановления партиции и успешных проверок снимите world_live с паузы, если он работал до упражнения.

Что должно получиться

  • вы переписали три файла sql/dds/order_*.sql, сохранив остальные части стенда;
  • вы удалили ближайший к окну закрытый день и увидели ошибку DQ до восстановления;
  • ваш расчет выбрал first_day с удаленного дня и заменил партиции всего отрезка до конца окна;
  • вы сверили число заказов и контрольную сумму восстановленного дня с сохраненными значениями; они совпали;
  • order_items_total, orders_vs_ods и пять прежних проверок успешны;
  • ваш запрос с hostName() не нашел заказов на чужом шарде;
  • повторный etl_pipeline сохранил деловые данные, проверки прошли.