fix(world): устранены расхождения после переноса на main
- Зачем: - свежий main добавил мониторинг и проявил устаревшие доводы, мёртвые настройки и слишком короткий тайм-аут DDL. - Что: - документация приведена к текущему жизненному циклу мира и составу стенда; - удалены лишняя проверка и неиспользуемый YAML-якорь; - ожидание ClickHouse возвращено к 300 секундам, а отказы и параметры DockerOperator пояснены. - Проверка: - `make config-test`; - `make lint`; - `make smoke` — 21/21.
This commit is contained in:
1 parent
7e6554507a
commit
bca1ffa379
8 files changed
+45
-34
No files matched your search
@@ -69,8 +69,8 @@ make check-services
|
||||
`superset-init` завершаются с кодом 0. Первый обновляет схему Airflow,
|
||||
подготавливает администратора и два подключения к `clickhouse-01`. Второй
|
||||
обновляет Superset, создаёт администратора и импортирует подключение к
|
||||
`clickhouse-02`.
|
||||
С нуля подъём занимает около трёх минут, на живом стенде — около минуты.
|
||||
`clickhouse-02`. На ноутбуке в режиме энергосбережения приёмочный подъём с
|
||||
пустых томов занял около десяти минут, повторный на живом стенде — около трёх.
|
||||
|
||||
`make smoke` за секунды спрашивает, собран ли стенд: зависимости машины,
|
||||
здоровье контейнеров, устройство keeper, ответ Kafka с машины через отображённый
|
||||
|
||||
@@ -46,10 +46,6 @@ x-kafka-target: &kafka-target
|
||||
<<: *kafka-common
|
||||
KAFKA_TOPIC: hits
|
||||
|
||||
x-orders-kafka-target: &orders-kafka-target
|
||||
<<: *kafka-common
|
||||
KAFKA_TOPIC: *orders-topic
|
||||
|
||||
x-world-starting-days: &world-starting-days "8"
|
||||
|
||||
x-airflow-common: &airflow-common
|
||||
|
||||
@@ -56,7 +56,9 @@ def _clickhouse_client():
|
||||
password=connection.password,
|
||||
database=connection.schema or "default",
|
||||
connect_timeout=5,
|
||||
send_receive_timeout=60,
|
||||
# `ON CLUSTER` ждёт хосты до 180 с. Транспорт живёт дольше, чтобы
|
||||
# ClickHouse сам назвал незавершённый хост вместо сетевого тайм-аута.
|
||||
send_receive_timeout=300,
|
||||
)
|
||||
|
||||
|
||||
@@ -97,7 +99,10 @@ def _generator(task_id: str, command: list[str]) -> DockerOperator:
|
||||
"KAFKA_BOOTSTRAP_SERVERS": KAFKA_BOOTSTRAP_SERVERS,
|
||||
"KAFKA_TOPIC": HITS_TOPIC,
|
||||
},
|
||||
# Вывод уже переехал в журнал задачи; завершённый контейнер не нужен.
|
||||
auto_remove="force",
|
||||
# Временный путь Airflow существует внутри контейнера, но монтировать
|
||||
# его пытается хостовый Docker. Генератору этот каталог не нужен.
|
||||
mount_tmp_dir=False,
|
||||
)
|
||||
|
||||
@@ -260,7 +265,9 @@ def world_initialize():
|
||||
finally:
|
||||
client.close()
|
||||
raise AirflowException(
|
||||
f"стартовый мир не принят за 300 с: строк {arrived} из {expected}"
|
||||
f"стартовый мир не принят за 300 с: строк {arrived} из {expected}; "
|
||||
"проверьте журнал send_initial_events и "
|
||||
"SELECT * FROM system.kafka_consumers"
|
||||
)
|
||||
|
||||
@task
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
обработчик DAG. Triggerer не запускается: в каркасе нет отложенных задач.
|
||||
Два интеграционных пробника написаны через публичный `airflow.sdk`.
|
||||
|
||||
Долгоживущие процессы Airflow зависят от `airflow-init`, а Superset — от
|
||||
`superset-init`. Это ребро нужно самому `up --wait`: Docker Compose 2.40.3
|
||||
считает успешно завершившийся одноразовый сервис без зависимого упавшим и
|
||||
возвращает единицу — поведение проверено при исполнении #37. Зависимость
|
||||
включает результат подготовки в общий граф ожидания.
|
||||
|
||||
Для входа выбран SimpleAuthManager. У него нет команды создания пользователя,
|
||||
поэтому `airflow-init` записывает пароль администратора из окружения в
|
||||
JSON-файл отдельного тома `airflow_auth`. Новый именованный том принадлежит
|
||||
|
||||
@@ -144,8 +144,10 @@ Keeper — отдельный сервис, системных таблиц у
|
||||
вышло восемь: четыре таблицы, каждая обеими нодами. Таблиц ошибок среди них
|
||||
нет, и это правда состояния — частей у них пока не появилось.
|
||||
- Очередь DDL показала `CREATE MATERIALIZED VIEW ... ON CLUSTER` в состоянии
|
||||
`Finished` и со временем по каждой ноде: `make generate-batch` поднимает
|
||||
`clickhouse-init`, и тот заново прогоняет DDL.
|
||||
`Finished` и со временем по каждой ноде. Новые безопасные записи для показа
|
||||
оставляет `make check-clickhouse`: цель создаёт и удаляет временные таблицы
|
||||
`ON CLUSTER`. Канонический DDL появляется в очереди при создании мира дагом
|
||||
`world_initialize`.
|
||||
|
||||
Подписи рядов (`${__field.labels.node}`) и правило, по которому пунктирным
|
||||
становится только ряд «отведено», сверены по документации Grafana через MCP
|
||||
|
||||
@@ -241,22 +241,26 @@ Kafka → STG → ODS, и живёт он в `make check-clickhouse`.
|
||||
19/2: назвал нездоровый сервис и отсутствие одной из четырёх целей. После
|
||||
возврата сервиса прогон снова дал 21/21.
|
||||
|
||||
**Приёмка #119 21 августа 2026 года.** `make rebuild-storage` через Airflow
|
||||
прошёл за 3 м 9 с: позиция прошла задачи `-1` → `0` → `8`, топики получили
|
||||
новые идентификаторы, группы дочитали новые топики без отставания, а ODS принял
|
||||
401 185 событий без брака и 2 851 актуальный заказ. Повторный `make up` занял
|
||||
2 м 41 с вместе со штатным повторным запуском служб инициализации;
|
||||
`world_initialize` завершился за один цикл опроса и оставил счётчики
|
||||
неизменными. Отдельно
|
||||
проверены красные отказы `world_initialize` при `-1` и `world_next_day` при
|
||||
отсутствующей позиции, `0` и `-1`; `lifecycle` отказано в чтении
|
||||
`system.users`, но разрешено чтение `system.settings`.
|
||||
После переноса #119 поверх этого состава повторный `make up` сохранил готовый
|
||||
мир, смоук прошёл 21/21, проверка ClickHouse — 10/10, межсервисная — 7/7.
|
||||
|
||||
**Приёмка логики #119 до переноса поверх мониторинга 21 августа 2026 года.**
|
||||
`make rebuild-storage` через Airflow прошёл за 3 м 9 с: позиция прошла задачи
|
||||
`-1` → `0` → `8`, топики получили новые идентификаторы, группы дочитали новые
|
||||
топики без отставания, а ODS принял 401 185 событий без брака и 2 851
|
||||
актуальный заказ. Задача `build_generator_image` заняла по 1,5 с в двух
|
||||
прогонах.
|
||||
Повторный `make up` занял 2 м 41 с вместе со штатным повторным запуском служб
|
||||
инициализации; `world_initialize` завершился за один цикл опроса и оставил
|
||||
счётчики неизменными. Отдельно проверены красные отказы `world_initialize` при
|
||||
`-1` и `world_next_day` при отсутствующей позиции, `0` и `-1`; `lifecycle`
|
||||
отказано в чтении `system.users`, но разрешено чтение `system.settings`.
|
||||
|
||||
Итоговый холодный `make up` из пустых томов занял 9 м 39 с после 25 с на
|
||||
`make clean`. Даг создал отсутствующую позицию и закончил на `8`; ODS снова
|
||||
получил 401 185 событий без брака и 2 851 заказ. У `hits` два раздела, у
|
||||
`orders` один, отставание обеих групп равно нулю. На этом стенде прошли смоук
|
||||
20/20, проверка ClickHouse 10/10 и межсервисная проверка 7/7.
|
||||
`orders` один, отставание обеих групп равно нулю. На тогдашнем составе стенда
|
||||
прошли смоук 20/20, проверка ClickHouse 10/10 и межсервисная проверка 7/7.
|
||||
|
||||
Оборванную очистку проверили после записи `world_position=-1`: остановили
|
||||
первую ноду ClickHouse, и `world_recreate` покраснел на удалении баз. Следующий
|
||||
|
||||
@@ -326,10 +326,10 @@
|
||||
- **Обрыв любого режима — переигровка дня целиком**; дедуп склеивает
|
||||
повторы: `WatchID` детерминированы, повтор — та же строка для
|
||||
ReplacingMergeTree.
|
||||
- **Эталонный снимок при старте стенда — через Kafka, пакетным режимом
|
||||
проигрывателя.** Отдельный механизм заливки не строится: каждый `make up`
|
||||
бесплатно прогоняет весь конвейер на настоящих данных, и строгий приём
|
||||
хранилища проверяет контракт тем же прогоном.
|
||||
- **Эталонный снимок при создании мира — через Kafka, пакетным режимом
|
||||
проигрывателя.** Отдельный механизм заливки не строится: `world_initialize`
|
||||
прогоняет весь конвейер на настоящих данных при первом `make up` и при явном
|
||||
`make rebuild-storage`. На готовом мире повторный `make up` заливку пропускает.
|
||||
Оговорка «если заливка уйдёт в десятки минут — вернуться к прямой
|
||||
загрузке» проверена при фиксации чисел: 14 × 50 тыс. ≈ 700 тыс. событий —
|
||||
расчётно минута-две, запас есть.
|
||||
@@ -361,10 +361,11 @@
|
||||
окном K = 7, дышащая зона и две волны недельной сезонности. Удлинение до
|
||||
месяца — дешёвый ход (пересборка описи), если понадобится.
|
||||
- **В git — только опись, снимок не хранится.** Снимок генерируется при
|
||||
`make up` и при проверках: артефакт — кэш чистой функции, кэш в git не
|
||||
хранят. Опись несёт паспорт мира, счётчики и хеши по дням; проверки
|
||||
создании мира и в проверках генератора: артефакт — кэш чистой функции, кэш в
|
||||
git не хранят. Опись несёт паспорт мира, счётчики и хеши по дням; проверки
|
||||
«пустой git diff» и «пересгенерируй день N — сравни хеш» живут на ней.
|
||||
Каждый `make up` — живая демонстрация детерминизма. Честная потеря —
|
||||
Первый `make up` пустого стенда — живая демонстрация детерминизма; готовый мир
|
||||
повторный подъём не пересчитывает. Честная потеря —
|
||||
страховка на случай платформенного бага: раньше менти с расходящимися
|
||||
байтами мог взять готовый снимок из git, теперь он упрётся в красный чек
|
||||
описи; смягчение — CI гоняет генерацию на amd64 и arm64.
|
||||
|
||||
@@ -62,11 +62,6 @@ jq -e '
|
||||
["kafka-init", "clickhouse-init", "world-init", "world-snapshots"] |
|
||||
all(. as $name | $services | has($name) | not)
|
||||
' >/dev/null <<<"$config_json"
|
||||
jq -e '
|
||||
.services.generator as $generator |
|
||||
((($generator.depends_on // {}) | has("kafka-init")) | not) and
|
||||
((($generator.depends_on // {}) | has("clickhouse-init")) | not)
|
||||
' >/dev/null <<<"$config_json"
|
||||
jq -e '
|
||||
.services["airflow-scheduler"] as $service |
|
||||
($service.environment.CLICKHOUSE_LIFECYCLE_PASSWORD | length > 0) and
|
||||
|
||||
Reference in new issue
Block a user