docs(world): описан жизненный цикл прикладного мира
- Зачем: - границы владения Compose и Airflow должны быть видны менти из одного источника истины. - Что: - добавлены спека и ADR жизненного цикла мира; - обновлены README, архитектурные справочники и прежние решения; - правило полной очистки записано как явное и проверяемое требование к агенту. - Проверка: - документация вычитана через `ai-text-lint` и `writing-for-agents`; - выполнена литературная вычитка русского текста; - `git diff --check`.
This commit is contained in:
1 parent
fc5244cc67
commit
7e6554507a
12 files changed
+499
-104
No files matched your search
@@ -67,8 +67,9 @@ make check-services
|
||||
стенд и ждёт здорового состояния долгоживущих контейнеров. В образ Airflow
|
||||
добавлены закреплённые клиенты ClickHouse и Kafka. Одноразовые `airflow-init` и
|
||||
`superset-init` завершаются с кодом 0. Первый обновляет схему Airflow,
|
||||
подготавливает администратора и подключение к `clickhouse-01`. Второй обновляет
|
||||
Superset, создаёт администратора и импортирует подключение к `clickhouse-02`.
|
||||
подготавливает администратора и два подключения к `clickhouse-01`. Второй
|
||||
обновляет Superset, создаёт администратора и импортирует подключение к
|
||||
`clickhouse-02`.
|
||||
С нуля подъём занимает около трёх минут, на живом стенде — около минуты.
|
||||
|
||||
`make smoke` за секунды спрашивает, собран ли стенд: зависимости машины,
|
||||
@@ -118,29 +119,33 @@ Kafka по той же причине спрашивают снаружи. Её
|
||||
поднятый стенд, сколько стоит прогон и куда класть новую — в
|
||||
[карте проверок](docs/architecture/testing.md).
|
||||
|
||||
Остановить контейнеры без удаления данных можно командой `make down`. Для
|
||||
полного сброса с удалением всех именованных томов используйте `make clean`.
|
||||
Повторный `make up` безопасен: одноразовая подготовка приложений идемпотентна.
|
||||
Остановить контейнеры без удаления данных можно командой `make down`. Если
|
||||
нужно вернуть прикладной мир к началу, `make rebuild-storage` запустит в
|
||||
Airflow его явную пересборку: удалит прикладные базы ClickHouse, топики и
|
||||
позиции потребителей Kafka, затем создаст схему и данные заново. Службы и их
|
||||
тома останутся на месте. `make clean` удаляет весь стенд вместе с именованными
|
||||
томами и для обычной разработки не нужен. Перед пересборкой поставьте
|
||||
`world_live` на паузу и дайте уже начатому работнику закончить день.
|
||||
|
||||
## Стартовый мир
|
||||
|
||||
Стенд поднимается не пустым: разовая служба `world-init` играет в топик `hits`
|
||||
первые восемь дней модельного времени — понедельник по понедельник, 401 185
|
||||
событий. Следом второй запуск того же генератора отправляет в топик `orders`
|
||||
семь слепков — за дни 0…6. Дальше оба источника разбирает хранилище, и к концу
|
||||
`make up` события лежат в `ods.event`, а заказы — в `ods.order_v`. Так у всякой
|
||||
лабы есть данные, и всегда одни и те же.
|
||||
Стенд поднимается не пустым: `make up` через REST API запускает даг Airflow
|
||||
`world_initialize`. Тот создаёт прикладные топики и схему, собирает образ
|
||||
генератора и играет в `hits` первые восемь дней модельного времени — понедельник
|
||||
по понедельник, 401 185 событий. Следом второй запуск генератора отправляет в
|
||||
`orders` семь слепков — за дни 0…6. Даг ждёт приёма обоих источников и только
|
||||
тогда ставит позицию мира в `8`. Так у всякой лабы есть данные, и всегда одни и
|
||||
те же.
|
||||
|
||||
Последний день намеренно неполон: события дня 7 уже приехали, а его слепок
|
||||
уедет только с первым ходом мира. Поэтому на свежем стенде правый край графика
|
||||
выручки отстаёт от кликстрима и дозаполняется по мере движения мира — так
|
||||
виден разный темп потокового трекера и ночной выгрузки магазина.
|
||||
|
||||
Ждать приходится дольше, чем работает заливка. `make up` сначала опрашивает
|
||||
ClickHouse, пока события не доедут, затем разово запускает даг `orders_ingest`
|
||||
и ждёт его конца. Повторный `make up` заливает мир заново; это не ошибка, а
|
||||
свойство: номера событий и версии заказов те же, и повторы схлопнут
|
||||
`ReplacingMergeTree`.
|
||||
Повторный `make up` безопасен: `world_initialize` видит готовую позицию,
|
||||
сообщает в журнале, что мир уже существует, и не применяет DDL, не собирает
|
||||
образ и не заливает данные повторно. Изменённую схему применяют адресно либо
|
||||
явной командой `make rebuild-storage`.
|
||||
|
||||
Сам мир в git не хранится — он чистая функция зерна, и держать его в
|
||||
репозитории значило бы держать там кэш. Вместо него лежит **опись мира**,
|
||||
@@ -202,9 +207,9 @@ make generate-live GENERATOR_DAY=3 GENERATOR_SPEED=1000
|
||||
docker compose --profile generator build generator
|
||||
```
|
||||
|
||||
Тот же образ несёт заливка стартового мира, поэтому свежим его держит и
|
||||
обычный `make up`: он собирает образы всего стенда, и генератор теперь среди
|
||||
них.
|
||||
Тот же образ несёт заливка стартового мира. Перед такой заливкой
|
||||
`world_initialize` сам собирает его из текущего дерева; на готовом мире
|
||||
повторный `make up` до сборки не доходит.
|
||||
|
||||
Разведено это нарочно: собрать образ и запустить контейнер — разные действия, и
|
||||
цель запуска, молча пересобирающая образ, стирает между ними границу. Что образ
|
||||
@@ -231,11 +236,13 @@ uv run --project generator python -m clickstream_generator batch \
|
||||
|
||||
### Пульт мира
|
||||
|
||||
Считать дни самому необязательно. В Airflow живёт **пульт мира** — три дага,
|
||||
которые зовут тот же образ генератора и ведут позицию на оси за вас.
|
||||
Считать дни самому необязательно. В Airflow живёт **пульт мира**: два дага
|
||||
создают его начальное состояние, а три двигают ось дальше.
|
||||
|
||||
| Даг | Что делает |
|
||||
| --- | --- |
|
||||
| `world_initialize` | создаёт стартовый мир, если его ещё нет; повторный запуск ничего не меняет |
|
||||
| `world_recreate` | удаляет только прикладной мир и запускает его создание заново |
|
||||
| `world_next_day` | играет следующие дни пачкой; сколько — параметр запуска, по умолчанию один |
|
||||
| `world_live_day` | играет следующий день в темпе модельного времени, около двадцати четырёх минут |
|
||||
| `world_live` | выключатель: пока снят с паузы, дёргает `world_live_day` день за днём |
|
||||
@@ -248,8 +255,10 @@ uv run --project generator python -m clickstream_generator batch \
|
||||
|
||||
Позицию хранит переменная Airflow `world_position` — номер первого несыгранного
|
||||
дня. Ставит её работник, сыгравший день, и только по успеху: оборванный прогон
|
||||
позицию не двигает, и следующий запуск играет тот же день заново. Нет
|
||||
переменной — мир в стартовом состоянии.
|
||||
позицию не двигает, и следующий запуск играет тот же день заново. Отсутствующая
|
||||
переменная означает, что мир ещё не создавали; `-1` — очистка не закончена,
|
||||
`0` — очистка закончена, а начальная генерация ещё не завершена. Работники
|
||||
начинают играть только с позиции `8` и больше.
|
||||
|
||||
Выключатель создаётся на паузе. Снимите — мир поедет сам; поставите обратно —
|
||||
встанет на границе модельных суток, доиграв начатый день. Форма пульта и доводы
|
||||
@@ -286,10 +295,12 @@ uv run --project generator python -m clickstream_generator batch \
|
||||
- Prometheus — `http://127.0.0.1:29090`;
|
||||
- Grafana — `http://127.0.0.1:23000`, пользователь `admin`, пароль `admin`.
|
||||
|
||||
В ClickHouse шесть пользователей и пять ролей:
|
||||
В ClickHouse семь пользователей и шесть ролей:
|
||||
|
||||
- `etl` применяет DDL и подключает Airflow; роль `etl_writer` читает и пишет
|
||||
слои хранилища;
|
||||
- `etl` подключает рабочие даги Airflow; роль `etl_writer` читает и пишет слои
|
||||
хранилища;
|
||||
- `lifecycle` применяет канонический DDL и пересоздаёт прикладные базы; роль
|
||||
`lifecycle_owner` не даёт эти административные права рабочим дагам;
|
||||
- `bi` подключает Superset; роль `bi_reader` читает справочники `dic` и будущие
|
||||
слои DDS и DM;
|
||||
- `analyst` предназначен для подключения человека и читает все слои и
|
||||
|
||||
Reference in new issue
Block a user