feat(dm): добавлены витрины выручки и трафика
Зачем: - Показать два ритма пересборки агрегатов на готовых витринах DM. Что: - Добавлены физические модели и публичные договоры revenue_daily и daily_traffic. - Добавлен dm_transform с оконной заменой выручки и полным пересчетом трафика. - Отрицательный опыт локального соединения через публичные _v зафиксирован; выбран явный GLOBAL LEFT JOIN. - Замены партиций сериализованы после подтвержденного OOM при трех одновременных задачах. - Обновлены архитектурные документы и мастер-спека. Проверка: - make lint, make config-test, make smoke, make check-clickhouse, make check-services. - Чистая сборка world_recreate, dds_transform и dm_transform; меры сверены с прямыми агрегатами.
This commit is contained in:
1 parent
c9bcacd63b
commit
da0477f0f1
12 files changed
+436
-25
No files matched your search
+54
-8
@@ -31,8 +31,8 @@
|
||||
витрины, на него ссылаются учебные задания;
|
||||
- `purchase_vs_orders` — сверка A+C с классами расхождений; зерно — заказ,
|
||||
шардирование сохраняет ко-локацию заказов по `cityHash64(order_id)`;
|
||||
- `daily_traffic` — пара «посетители» / «известные пользователи», локальное
|
||||
обогащение [картой идентичностей](dds/identity.md);
|
||||
- `daily_traffic` — пара «посетители» / «известные пользователи», обогащение
|
||||
[картой идентичностей](dds/identity.md);
|
||||
- `dq_summary` — сводка проверок качества (ниже).
|
||||
|
||||
Остальные витрины спеки — учебные задания: менти строит их сам по ТЗ с
|
||||
@@ -55,8 +55,8 @@
|
||||
|
||||
- **от событий и сессий** — день замерзает сразу; пересборка догоняет
|
||||
хвост несобранных дней заменой дневных партиций;
|
||||
- **от заказов** — день дышит окном K и закрывается; пересборка заменяет
|
||||
партиции окна, дни за ним закрыты по построению;
|
||||
- **от заказов** — день дышит, пока входит в последний слепок; пересборка
|
||||
заменяет партиции этого отрезка, дни за ним закрыты по построению;
|
||||
- **от карты идентичностей** — не замерзает никогда: склейка
|
||||
ретроспективна, покупка сегодня делает куку известной во всех её прошлых
|
||||
днях, а карта пересчитывается целиком.
|
||||
@@ -64,12 +64,58 @@
|
||||
Поэтому `daily_traffic` наследует у своего источника и ритм, и механику:
|
||||
полный пересчёт всех дней каждый прогон в `ReplacingMergeTree(_load_ts)`,
|
||||
как у самой карты. Дневных партиций у неё нет: партиция — единица замены,
|
||||
а эта витрина заменяется только целиком. Пересчёт дешёв:
|
||||
витрина читает сессии и карту локальным соединением по ключу ко-локации.
|
||||
а эта витрина заменяется только целиком. На стенде такая работа остается
|
||||
быстрой; витрина читает сессии и карту через их публичные договоры.
|
||||
Пересчитывать точечно только затронутые дни не из чего: для этого надо
|
||||
знать, какие связки новые, а полный пересчёт карты этот след затирает —
|
||||
восстановление следа оставлено лабе повышенной сложности (issue #149).
|
||||
|
||||
## Витрины стенда
|
||||
|
||||
Оба публичных представления перечисляют деловые колонки и координаты запуска
|
||||
`_load_id`, `_load_ts` явно. Новая колонка физической таблицы сама в договор не
|
||||
попадет.
|
||||
|
||||
### `dm.revenue_daily_v`
|
||||
|
||||
Зерно: день заказа × категория товара. Витрина читает только оплаченные
|
||||
заказы из `dds.order_v`, синхронно разворачивает три массива позиций и узнает
|
||||
категорию артикула через `dic.products`. Один заказ с несколькими позициями
|
||||
категории считается в `orders` один раз. `units` складывает количество единиц,
|
||||
`revenue` складывает цену позиции × количество. Скидка, доставка и итог заказа
|
||||
между категориями не делятся. `aov` равен `revenue / orders` в том же срезе и
|
||||
хранит два знака после запятой.
|
||||
|
||||
Первый запуск строит всю доступную историю. Следующие берут границы дней из
|
||||
последнего слепка ODS: только источник знает, какие даты еще может изменить.
|
||||
Пропущенный оплаченный день расширяет левую границу, чтобы частичный отказ
|
||||
не оставил дыру после следующего прогона. Агрегат при этом читает DDS; ODS
|
||||
отвечает только на вопрос об объеме.
|
||||
|
||||
`dm.revenue_daily_rep` нарезана по `report_date`; день собирается в
|
||||
таблице-доноре и заменяется через `REPLACE PARTITION`. Цель и донор шардируются
|
||||
по `cityHash64(product_category)`. Кроме дня, у витрины только категория, а
|
||||
шесть категорий стартового мира близки по объему. Более сложный составной ключ
|
||||
распределил бы эту маленькую таблицу без нового урока.
|
||||
|
||||
### `dm.daily_traffic_v`
|
||||
|
||||
В строке один день. `visitors` считает разные `client_id` из
|
||||
`dds.session_v`; `known_users` считает разные `user_id` после левого соединения
|
||||
с полной текущей `dds.identity_map_v`. Анонимная сессия остается в витрине.
|
||||
Несколько кук одного человека увеличивают `visitors`, но дают одного
|
||||
`known_user`, поэтому `known_users <= visitors`.
|
||||
|
||||
Сессии и карта лежат по `client_id`, но публичные `_v` скрывают
|
||||
`Distributed`-таблицы от локальной подстановки. На ClickHouse 26.3
|
||||
`EXPLAIN PLAN` показал чтение обоих шардов на инициаторе: настройка
|
||||
`distributed_product_mode = 'local'` локального соединения не дала. Поэтому
|
||||
витрина использует явный `GLOBAL LEFT JOIN` через публичные договоры, а не
|
||||
подменяет их физическими таблицами. Это дороже по сети, зато граница слоев
|
||||
остается явной. Новая связь куки меняет прошлые дни, поэтому каждый запуск
|
||||
пишет полную историю новой версией в `ReplacingMergeTree(_load_ts)`, а
|
||||
публичное представление выбирает текущие строки через `FINAL`.
|
||||
|
||||
## `dm.dq_summary`
|
||||
|
||||
Зерно — «день данных × проверка»: строка отвечает, каково качество дня
|
||||
@@ -113,7 +159,7 @@ Airflow. Партиция — день данных; прогон звена DQ
|
||||
|
||||
## Остаётся нарезке
|
||||
|
||||
- Имена задач `dm_transform`, звена DQ и дага самопроверки.
|
||||
- Имена звена DQ и дага самопроверки.
|
||||
- Ключи шардирования остальных материализованных витрин — вместе с их
|
||||
DDL; правило партиции-донора — в [доке хранилища](storage.md).
|
||||
- Тексты учебных заданий и точный список проверок обоих контуров.
|
||||
@@ -136,7 +182,7 @@ Airflow. Партиция — день данных; прогон звена DQ
|
||||
расшифровывать. Красное «ещё не построено» честнее.
|
||||
- **Самопроверка пишет в `dq_summary`.** Попытки менти смешались бы с
|
||||
историей качества конвейера.
|
||||
- **Окно K для `daily_traffic` — прошлое замерзает.** Дни за окном хранили
|
||||
- **Окно заказов для `daily_traffic` — прошлое замерзает.** Дни за окном хранили
|
||||
бы число известных на момент закрытия — витрина тихо расходится с картой
|
||||
и протаскивает обратно «знание на дату», отвергнутое развилкой карты
|
||||
(#133).
|
||||
|
||||
Reference in new issue
Block a user