docs(glossary): четыре термина переименованы, world.md и stand.md вычитаны
- Зачем:
- справочники читает человек со стороны, а «пульт мира», «опись мира»,
«работник» и «сырьё» звучали шуткой или калькой времён разработки
(тикет #214, выбор владельца).
- Что:
- CONTEXT.md: статьи «Паспорт мира», «Даги модельного времени»,
«Шаговый даг», «Сырые данные», старые слова в строках «Избегать»;
пометки в ADR 0005, 0008, 0009 без переписывания решений.
- замены по README, справочникам, путеводителю, лабам, спекам,
комментариям дагов и SQL, тегу дага и панели Grafana; имена в коде
не тронуты.
- world.md и stand.md: 35 находок вычитки внесены, регистр выровнен.
- Проверка:
- make config-test; make lint в корне и в generator/; make test в
generator/ (437 passed); скрипт ссылок из #212 пуст; grep старых
слов вне ADR, research и CONTEXT.md пуст.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QBCtU38qSHg5DvgtnKXcW
This commit is contained in:
1 parent
86ad8afaf2
commit
59d8c83b17
54 files changed
+794
-776
No files matched your search
@@ -272,12 +272,13 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
||||
Классы пересекаются — приоритет: `cancelled` > `lost_event` >
|
||||
`duplicate_event` > `amount_delta` > `match`.
|
||||
|
||||
Пятое — **опоздание** — бесплатно даёт формат доставки: часть заказов
|
||||
впервые появляется в слепке D+1/D+2 («вчера не сходилось, сегодня сошлось»),
|
||||
ориентир ~10%. Точные доли зафиксированы замером на каноническом мире
|
||||
(28 дней, 2026-08-30, #194) — запись в «Что проверено»
|
||||
[карты проверок](../architecture/testing.md); опись хранит счётчики наблюдаемых классов после приоритета — в заказах и
|
||||
только по дням с закрытым окном (раздел 8).
|
||||
Пятое — **опоздание** — бесплатно даёт формат доставки: часть заказов впервые
|
||||
появляется в слепке D+1/D+2 («вчера не сходилось, сегодня сошлось»), ориентир
|
||||
~10%. Точные доли зафиксированы замером на каноническом мире (28 дней,
|
||||
2026-08-30, #194) — запись в «Что проверено» [карты
|
||||
проверок](../architecture/testing.md); паспорт хранит счётчики наблюдаемых
|
||||
классов после приоритета — в заказах и только по дням с закрытым окном (раздел
|
||||
8).
|
||||
|
||||
Не берём: сироту-фрод (`purchase` есть, а заказа не будет никогда) —
|
||||
механически дублирует B.
|
||||
@@ -311,14 +312,13 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
||||
запуск пишет полный текущий набор различных пар; предыдущий результат не
|
||||
служит источником следующего.
|
||||
- **N:1**: часть покупателей покупает с двух кук («телефон и ноутбук») —
|
||||
параметр мира; значение фиксирует эта спека: 15%, детерминировано
|
||||
от seed. Ядро лабы:
|
||||
`uniq(посетителей) > uniq(людей)`, менти выводит расхождение сам.
|
||||
Константа мира: каждый двухкуковый покупатель делает минимум по одному
|
||||
заказу с каждой куки — иначе вторая кука не попадает в карту соответствий
|
||||
(она строится только из покупок) и лаба не воспроизводится. Число таких
|
||||
пар растёт, пока мир едет, и в опись не кладётся
|
||||
([что хранит опись](../architecture/orders/inventory.md)).
|
||||
параметр мира; значение фиксирует эта спека: 15%, детерминировано от seed.
|
||||
Ядро лабы: `uniq(посетителей) > uniq(людей)`, менти выводит расхождение сам.
|
||||
Константа мира: каждый двухкуковый покупатель делает минимум по одному заказу
|
||||
с каждой куки — иначе вторая кука не попадает в карту соответствий (она
|
||||
строится только из покупок) и лаба не воспроизводится. Число таких пар растёт,
|
||||
пока мир едет, и в паспорт не кладётся ([что хранит
|
||||
паспорт](../architecture/orders/inventory.md)).
|
||||
- Витрины разводят имена честно: **«посетители»** (`uniq(ClientID)`) и
|
||||
**«известные пользователи»** (после склейки) — оба числа рядом в дашборде.
|
||||
|
||||
@@ -339,16 +339,14 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
||||
ноду 2**. Это осознанная ловушка правильных ошибок: забытый ON CLUSTER или
|
||||
VIEW поверх локальной таблицы проявляются в дашборде сами.
|
||||
- **Приём Kafka**: у событий — Kafka-таблицы и MV на обеих нодах, одна
|
||||
consumer group, 2 партиции на топик `hits`; MV пишут в Distributed-цели.
|
||||
У заказов приём другого рода — пакетный забор без MV, чтец на одной ноде,
|
||||
топик `orders` в одну партицию ([ADR 0008](../adr/0008-order-ingestion.md)).
|
||||
Раскладку в обоих случаях решает ключ:
|
||||
события — по `cityHash64(ClientID)` (см. 1.3), заказы —
|
||||
`cityHash64(order_id)`, сырьё STG — `cityHash64(сырой строки)`; полный
|
||||
список и доводы — в [доке хранилища](../architecture/storage.md). Урок
|
||||
«какая нода читала топик — меняется между прогонами, куда легли данные —
|
||||
нет» живёт на событиях: при пакетном заборе читает та нода, которую
|
||||
спросили.
|
||||
consumer group, 2 партиции на топик `hits`; MV пишут в Distributed-цели. У
|
||||
заказов приём другого рода — пакетный забор без MV, чтец на одной ноде, топик
|
||||
`orders` в одну партицию ([ADR 0008](../adr/0008-order-ingestion.md)).
|
||||
Раскладку в обоих случаях решает ключ: события — по `cityHash64(ClientID)`
|
||||
(см. 1.3), заказы — `cityHash64(order_id)`, STG — `cityHash64(сырой строки)`;
|
||||
полный список и доводы — в [доке хранилища](../architecture/storage.md). Урок
|
||||
«какая нода читала топик — меняется между прогонами, куда легли данные — нет»
|
||||
живёт на событиях: при пакетном заборе читает та нода, которую спросили.
|
||||
- **Приём строгий**: пять опорных колонок — `WatchID`, `VisitID`, `ClientID`,
|
||||
`EventDate`, `UTCEventTime` — разбираются как `Nullable`, а набор ключей
|
||||
сообщения сверяется с контрактным; строка с NULL среди опорных колонок
|
||||
@@ -444,23 +442,24 @@ README.
|
||||
| DM | витрины `dm.*_v`, `dm.dq_summary` | см. ниже |
|
||||
|
||||
У каждой таблицы слоя — пара из локальной и распределённой, имена по конвенции
|
||||
суффиксов; она же задаёт служебные колонки, нарезку и срок хранения сырья —
|
||||
см. [доку хранилища](../architecture/storage.md).
|
||||
Потребительские запросы и витрины читают сущности DDS через `_v` с явным
|
||||
списком колонок; `_rep` и `_dist` служат загрузке, диагностике и обслуживанию.
|
||||
Договор держится конвенцией, а не правами: модель доступа описана в
|
||||
[ADR 0007](../adr/0007-clickhouse-access.md), договор чтения — в
|
||||
[доке хранилища](../architecture/storage.md), «Имена объектов».
|
||||
суффиксов; она же задаёт служебные колонки, нарезку и срок хранения сырых данных
|
||||
— см. [доку хранилища](../architecture/storage.md). Потребительские запросы и
|
||||
витрины читают сущности DDS через `_v` с явным списком колонок; `_rep` и `_dist`
|
||||
служат загрузке, диагностике и обслуживанию. Договор держится конвенцией, а не
|
||||
правами: модель доступа описана в [ADR 0007](../adr/0007-clickhouse-access.md),
|
||||
договор чтения — в [доке хранилища](../architecture/storage.md), «Имена
|
||||
объектов».
|
||||
|
||||
Заказы принимаются **пакетным забором** ([ADR
|
||||
0008](../adr/0008-order-ingestion.md), [ADR
|
||||
0010](../adr/0010-order-versions-in-ods.md)): чтец топика байтовый, как у событий, но
|
||||
матвью к нему не привязана, и сырьё забирает шаг, которым управляет Airflow —
|
||||
одно прямое чтение вставляет порцию в `stg.orders_raw` с `_load_id` запуска.
|
||||
Один следующий `task_id` двумя последовательными запросами пишет годные строки
|
||||
и ошибки из того же среза. `ods.order` выбирает текущую версию по максимальной
|
||||
`snapshot_date` ([ADR 0014](../adr/0014-order-version-snapshot-date.md)). Слой
|
||||
сырья остаётся точкой повтора и разбора одной принятой порции.
|
||||
0010](../adr/0010-order-versions-in-ods.md)): чтец топика байтовый, как у
|
||||
событий, но матвью к нему не привязана, и порцию в STG забирает шаг под
|
||||
управлением Airflow — одно прямое чтение вставляет её в `stg.orders_raw` с
|
||||
`_load_id` запуска. Один следующий `task_id` двумя последовательными запросами
|
||||
пишет годные строки и ошибки из того же среза. `ods.order` выбирает текущую
|
||||
версию по максимальной `snapshot_date` ([ADR
|
||||
0014](../adr/0014-order-version-snapshot-date.md)). Слой Сырой слой остаётся
|
||||
точкой повтора и разбора одной принятой порции.
|
||||
|
||||
Состав служебных колонок задаёт дока хранилища. Спеке важны два следствия:
|
||||
`ods.event` и `ods.order` получают метку загрузки `_load_ts`, но версию
|
||||
@@ -531,31 +530,28 @@ Kafka день переигрывается генератором заново:
|
||||
пачками), Postgres остаётся только служебной базой Airflow. Смешанность
|
||||
ландшафта выражена режимами и частотами, а не второй трубой.
|
||||
|
||||
## 8. Эталонный мир и опись
|
||||
## 8. Эталонный мир и паспорт
|
||||
|
||||
В git хранится только опись эталонного мира; сам снимок генерируется на
|
||||
месте — при `make up` и при проверках (решение развилки «Производительность»
|
||||
карты #26, подробности — [спека генератора](2026-08-01-generator.md),
|
||||
раздел 5). Снимок — 8 дней, совпадает со стартовым миром: обещание в 14 дней
|
||||
снято на этапе 7. Опись несёт
|
||||
паспорт мира (каноническое зерно, версия генератора), контрольные счётчики
|
||||
и хеши по дням; проверки «пустой git diff» и «пересгенерируй день N —
|
||||
сравни хеш» живут на ней. Политика версионирования артефакта (бывший туман
|
||||
карты #10) закрыта этим же ходом: версионируется опись.
|
||||
Контрольные числа описи:
|
||||
В git хранится только паспорт эталонного мира; сам снимок генерируется на месте
|
||||
— при `make up` и при проверках (решение развилки «Производительность» карты
|
||||
#26, подробности — [спека генератора](2026-08-01-generator.md), раздел 5).
|
||||
Снимок — 8 дней, совпадает со стартовым миром: обещание в 14 дней снято на этапе
|
||||
7. Паспорт несёт шапку с каноническим зерном и версией генератора, контрольные
|
||||
счётчики и хеши по дням; проверки «пустой git diff» и «пересгенерируй день N —
|
||||
сравни хеш» живут на нём. Политика версионирования артефакта (бывший туман карты
|
||||
#10) закрыта этим же ходом: версионируется паспорт. Контрольные числа паспорта:
|
||||
|
||||
- по строке на каждый отправленный слепок — хеш байтов: побайтовое обещание
|
||||
«слепок переснимается и даёт те же байты» опись сторожит наравне с днями;
|
||||
«слепок переснимается и даёт те же байты» паспорт сторожит наравне с днями;
|
||||
- заказная сторона: счётчики наблюдаемых классов расхождений после
|
||||
приоритета; каждый показывает число заказов и хранится только для дня с
|
||||
закрытым окном (читатель — техническая проверка `classes_vs_inventory`
|
||||
звена DQ; при N сыгранных днях таких дней N − 7). Отдельных полей для
|
||||
общего числа заказов и выручки в описи пока нет: для них не назван
|
||||
читатель;
|
||||
закрытым окном (читатель — техническая проверка `classes_vs_inventory` звена
|
||||
DQ; при N сыгранных днях таких дней N − 7). Отдельных полей для общего числа
|
||||
заказов и выручки в паспорте пока нет: для них не назван читатель;
|
||||
- контрольные числа идентичности не заводятся: uniq известных пользователей
|
||||
и число двухкуковых покупателей растут, пока мир едет, а счётчик без
|
||||
названного читателя в опись не кладётся
|
||||
([что хранит опись](../architecture/orders/inventory.md)).
|
||||
названного читателя в паспорт не кладётся ([что хранит
|
||||
паспорт](../architecture/orders/inventory.md)).
|
||||
|
||||
Размер снимка замерен на этапе 7 — запись в разделе «Что проверено»
|
||||
[карты проверок](../architecture/testing.md).
|
||||
@@ -572,7 +568,7 @@ v2 стартует пустым, поэтому объём ниже — это
|
||||
| SQL | DDL по слоям и ролям (ON CLUSTER, Replicated*, Distributed; раскладка файлов — в доке хранилища) + трансформации событий, заказов, identity, сверки + словарь | L — ~12–15 файлов, главная сложность |
|
||||
| Airflow | DAG'и по образцу v1: etl_pipeline (партиционная переобработка), world_init/next_day, helpers; первый даг — переливка слепка — приходит раньше, этапом 3 | M — ~5–6 файлов |
|
||||
| Superset | датасеты + дашборд с тремя новыми сюжетами | M — 2 файла |
|
||||
| Эталонный мир | пересборка снимка на месте, счётчики описи, чек-скрипты | M–L |
|
||||
| Эталонный мир | пересборка снимка на месте, счётчики паспорта, чек-скрипты | M–L |
|
||||
| Мониторинг | дашборды Grafana «данные», «кластер», «запросы»; ClickHouse источником данных, панели на SQL; Prometheus тонким полом (ADR 0002) | M — конфиги и дашборды |
|
||||
| Документация | доки v2 пишутся заново (см. раздел 12) | M, в тех же PR |
|
||||
|
||||
@@ -619,8 +615,8 @@ v2 стартует пустым, поэтому объём ниже — это
|
||||
4. Трансформации и витрины: модель DDS заказа, сессии, identity_map,
|
||||
выручка, сверка A+C.
|
||||
5. Airflow: `etl_pipeline` (партиционная переобработка).
|
||||
6. Расхождения B+D и опоздания; счётчики описи.
|
||||
7. Эталонный мир: опись и пересборка снимка, чек-скрипты. CI-генерация
|
||||
6. Расхождения B+D и опоздания; счётчики паспорта.
|
||||
7. Эталонный мир: паспорт и пересборка снимка, чек-скрипты. CI-генерация
|
||||
снята (спека генератора, раздел 5).
|
||||
8. Superset-дашборд v2.
|
||||
9. Мониторинг и runbook «keeper упал / DDL повис в очереди». Состав дашбордов
|
||||
@@ -658,15 +654,15 @@ ADR 0002 с приёмочными совпадают почти целиком.
|
||||
расхождение часов клиент/коллектор — туман карты, вернётся своим тикетом.
|
||||
- Лабы и курс: v2 — другой стенд, лабы для него пишутся с нуля отдельной
|
||||
работой после этой спеки; редизайн лаб v1 (#7) остаётся в v1 и сюда не
|
||||
переносится. Исключение — домашки слоя DM: ТЗ витрин менти и даг
|
||||
самопроверки забраны в этап 4 резолюцией #135, потому что витрина менти и
|
||||
конвейер, в который она встает, проектируются вместе. Сюда же —
|
||||
необязательная лаба «свой дашборд в Superset» (#197): она стоит на
|
||||
витринах домашек DM и продумана до готового ТЗ в этапе 8, тогда как
|
||||
остальные лабы пока на уровне идей. Единый стиль блока
|
||||
домашек — за работой учебного пути. Спека даёт будущим лабам только
|
||||
опорные точки — контрольные числа описи (сверка, идентичность). Явное
|
||||
следствие: после этапа 9 стенд работает, но учебного пути на нём ещё нет.
|
||||
переносится. Исключение — домашки слоя DM: ТЗ витрин менти и даг самопроверки
|
||||
забраны в этап 4 резолюцией #135, потому что витрина менти и конвейер, в
|
||||
который она встает, проектируются вместе. Сюда же — необязательная лаба «свой
|
||||
дашборд в Superset» (#197): она стоит на витринах домашек DM и продумана до
|
||||
готового ТЗ в этапе 8, тогда как остальные лабы пока на уровне идей. Единый
|
||||
стиль блока домашек — за работой учебного пути. Спека даёт будущим лабам
|
||||
только опорные точки — контрольные числа паспорта (сверка, идентичность).
|
||||
Явное следствие: после этапа 9 стенд работает, но учебного пути на нём ещё
|
||||
нет.
|
||||
- Инкрементальный ETL (#8) — свой issue.
|
||||
- Реплики (2×2), HAProxy, репликационная эксплуатация — в лекцию, не в стенд.
|
||||
- TLS между нодами, настоящее хранилище и ротация секретов, внешние учётные
|
||||
|
||||
Reference in new issue
Block a user