feat(stand): make up наполняет стенд стартовым миром, опись сторожит его
Зачем Стенд поднимался пустым, и всякая приёмка следующих этапов начиналась с ручной заливки данных. Теперь `make up` сам приводит стенд к одному и тому же состоянию, а в git лежит то, чем это состояние проверяется. Что - Опись мира `data/world-inventory.json`: паспорт (зерно, версия генератора, хеш каталога) и по строке на каждый из восьми дней — дата, число событий, хеш байтов. Собирается `make inventory`, свежесть сторожит `test_inventory.py` — тем же способом, что свежесть описания выгрузки. - Разовая служба `world-init` вышла из-под профиля и играет в топик восемь дней при каждом подъёме; зависимый у неё — `airflow-init`, иначе `--wait` считает успешно отработавшую службу упавшей. - `scripts/wait-for-world.sh` — вторая половина `make up`: приём асинхронный, поэтому ждать надо доезда до `ods.event`, а не завершения заливки. Ограниченный цикл опроса, не пауза наугад. - Девятая проверка `make check-clickhouse`: подневный счёт событий против описи, рамка по датам стартового мира, счёт через `FINAL`. При расхождении называет, где искать, — в событиях или в браке. - Порог «день ≤ 30 с» снят из спеки генератора в обоих местах: замер дал 1,7 с, порог был выше факта в восемнадцать раз. На его месте — замеры с датой. Раздел 9 спеки закрыт: открытых вопросов не осталось. - Слова: «манифест» стал описью мира, «зерновой мир» — стартовым миром (решение владельца). Оба заведены в словарь CONTEXT.md. Проверка `make clean && make up` с нуля — 2 м 50 с, доехало ровно 401 185 событий. `make check-clickhouse` зелёный (8 с), `make smoke` зелёный (9 с), `make test` — 407 тестов за 71 с, `make lint`, `make typecheck`, `make config-test` зелёные. Что проверка умеет краснеть, снято двумя поломками: снос партиции 2026-06-03 дал диагноз «не доехали до ODS», негодная строка в сырье — «сломан разбор». Строки опыта убраны, день переигран, счёт вернулся. Тест свежести проверен молчаливой правкой цены в каталоге: покраснел. Ссылка: #42
This commit is contained in:
1 parent
30a1e9e567
commit
7c9eeedc40
20 files changed
+625
-132
No files matched your search
@@ -253,7 +253,7 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
||||
Пятое — **опоздание** — бесплатно даёт формат доставки: часть заказов
|
||||
впервые появляется в слепке D+1/D+2 («вчера не сходилось, сегодня сошлось»),
|
||||
ориентир ~10%. Точные доли фиксируются при пересборке эталонного мира;
|
||||
манифест хранит точные счётчики по каждому классу расхождений (отмены,
|
||||
опись хранит точные счётчики по каждому классу расхождений (отмены,
|
||||
потери, дубли).
|
||||
|
||||
Не берём: сироту-фрод (`purchase` есть, а заказа не будет никогда) —
|
||||
@@ -286,7 +286,7 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
||||
`uniq(посетителей) > uniq(людей)`, менти выводит расхождение сам.
|
||||
Константа мира: каждый двухкуковый покупатель делает минимум по одному
|
||||
заказу с каждой куки — иначе вторая кука не попадает в карту соответствий
|
||||
(она строится только из покупок) и лаба не воспроизводится. Манифест
|
||||
(она строится только из покупок) и лаба не воспроизводится. Опись
|
||||
хранит число именно таких пар.
|
||||
- Витрины разводят имена честно: **«посетители»** (`uniq(ClientID)`) и
|
||||
**«известные пользователи»** (после склейки) — оба числа рядом в дашборде.
|
||||
@@ -464,19 +464,19 @@ Kafka день переигрывается генератором заново:
|
||||
пачками), Postgres остаётся только служебной базой Airflow. Смешанность
|
||||
ландшафта выражена режимами и частотами, а не второй трубой.
|
||||
|
||||
## 8. Эталонный мир и манифест
|
||||
## 8. Эталонный мир и опись
|
||||
|
||||
В git хранится только манифест эталонного мира; сам снимок (14 модельных
|
||||
В git хранится только опись эталонного мира; сам снимок (14 модельных
|
||||
дней) генерируется на месте — при `make up` и при проверках (решение
|
||||
развилки «Производительность» карты #26, подробности —
|
||||
[спека генератора](2026-08-01-generator.md), раздел 5). Манифест несёт
|
||||
[спека генератора](2026-08-01-generator.md), раздел 5). Опись несёт
|
||||
паспорт мира (каноническое зерно, версия генератора), контрольные счётчики
|
||||
и хеши по дням; проверки «пустой git diff» и «пересгенерируй день N —
|
||||
сравни хеш» живут на нём. Политика версионирования артефакта (бывший туман
|
||||
карты #10) закрыта этим же ходом: версионируется манифест.
|
||||
Контрольные числа манифеста:
|
||||
сравни хеш» живут на ней. Политика версионирования артефакта (бывший туман
|
||||
карты #10) закрыта этим же ходом: версионируется опись.
|
||||
Контрольные числа описи:
|
||||
|
||||
- заказная сторона: заказы и выручка по дням; манифест хранит точные
|
||||
- заказная сторона: заказы и выручка по дням; опись хранит точные
|
||||
счётчики по каждому классу расхождений (отмены, потери, дубли, дельты сумм) —
|
||||
самопроверка лабы сверки;
|
||||
- идентичность: uniq кук, uniq известных пользователей, число двухкуковых
|
||||
@@ -497,7 +497,7 @@ v2 стартует пустым, поэтому объём ниже — это
|
||||
| SQL | DDL по слоям и ролям (ON CLUSTER, Replicated*, Distributed; раскладка файлов — в доке хранилища) + трансформации событий, заказов, identity, сверки + словарь | L — ~12–15 файлов, главная сложность |
|
||||
| Airflow | DAG'и по образцу v1: etl_pipeline (партиционная переобработка, ожидание дневного батча заказов — сенсор/Datasets), world_init/next_day, helpers | M — ~5–6 файлов |
|
||||
| Superset | датасеты + дашборд с тремя новыми сюжетами | M — 2 файла |
|
||||
| Эталонный мир | пересборка снимка на месте, манифест-счётчики, чек-скрипты | M–L |
|
||||
| Эталонный мир | пересборка снимка на месте, счётчики описи, чек-скрипты | M–L |
|
||||
| Мониторинг | дашборды Grafana «данные», «кластер», «запросы»; ClickHouse источником данных, панели на SQL; Prometheus тонким полом (ADR 0002) | M — конфиги и дашборды |
|
||||
| Документация | доки v2 пишутся заново (см. раздел 12) | M, в тех же PR |
|
||||
|
||||
@@ -534,15 +534,15 @@ v2 стартует пустым, поэтому объём ниже — это
|
||||
2. DDL и генератор (слиты в один этап — DDL проверяется только настоящими
|
||||
данными): базы и таблицы событий ON CLUSTER, приём `hits` обеими нодами;
|
||||
широкое событие, таксономия, анонимность, N:1 (клиентская сторона
|
||||
целиком). В конце этапа фиксируется маленький «зерновой» мир для
|
||||
целиком). В конце этапа фиксируется маленький стартовый мир для
|
||||
стабильных приёмок следующих этапов (полная пересборка эталонного мира —
|
||||
отдельный этап 7).
|
||||
3. Заказы и каталог: генератор слепков, STG/ODS/DDS заказа, словарь.
|
||||
4. Трансформации и витрины: сессии, identity_map, выручка, сверка A+C.
|
||||
5. Airflow: `etl_pipeline` (партиционная переобработка, ожидание дневного
|
||||
батча заказов — сенсор/Datasets).
|
||||
6. Расхождения B+D и опоздания; счётчики манифеста.
|
||||
7. Эталонный мир: манифест и пересборка снимка, чек-скрипты; CI-генерация
|
||||
6. Расхождения B+D и опоздания; счётчики описи.
|
||||
7. Эталонный мир: опись и пересборка снимка, чек-скрипты; CI-генерация
|
||||
на amd64 и arm64.
|
||||
8. Superset-дашборд v2.
|
||||
9. Мониторинг и runbook «keeper упал / DDL повис в очереди». Состав дашбордов
|
||||
@@ -563,7 +563,7 @@ v2 стартует пустым, поэтому объём ниже — это
|
||||
- Лабы и курс: v2 — другой стенд, лабы для него пишутся с нуля отдельной
|
||||
работой после этой спеки; редизайн лаб v1 (#7) остаётся в v1 и сюда не
|
||||
переносится. Спека даёт будущим лабам только опорные точки — контрольные
|
||||
числа манифеста (сверка, идентичность). Явное следствие: после этапа 9
|
||||
числа описи (сверка, идентичность). Явное следствие: после этапа 9
|
||||
стенд работает, но учебного пути на нём ещё нет.
|
||||
- Инкрементальный ETL (#8) — свой issue.
|
||||
- Реплики (2×2), HAProxy, репликационная эксплуатация — в лекцию, не в стенд.
|
||||
|
||||
Reference in new issue
Block a user