Files
clickstream-data-platform/docs/adr/0001-stand-services.md
T
Dmitry Dementiev 1f203c974d fix(compose): устранена гонка сборки общих образов
- Зачем:
  - make up иногда падал, когда несколько служб параллельно экспортировали один тег образа.
- Что:
  - сборка образов Airflow и Superset закреплена за службами инициализации.
  - зависимые службы только используют готовый образ, решение описано в ADR 0001.
- Проверка:
  - make config-test.
  - docker compose --progress plain build superset superset-init airflow-scheduler airflow-init.
  - два запуска make up прошли экспорт трёх уникальных тегов без image already exists.
2026-08-28 12:53:33 +03:00

9.9 KiB
Raw Blame History

ADR 0001. Сервисы каркаса стенда

Дата: 30 июля 2026 года. Статус: принято; ресурсный довод отозван ADR 0004.

Решение

Стенд использует Airflow 3.3.0 с LocalExecutor. Airflow разделён на одноразовый airflow-init и три долгоживущих процесса: API, планировщик и обработчик DAG. Triggerer не запускается: в каркасе нет отложенных задач. Два интеграционных пробника написаны через публичный airflow.sdk.

Долгоживущие процессы Airflow зависят от airflow-init, а Superset — от superset-init. Это ребро нужно самому up --wait: Docker Compose 2.40.3 считает успешно завершившийся одноразовый сервис без зависимого упавшим и возвращает единицу — поведение проверено при исполнении #37. Зависимость включает результат подготовки в общий граф ожидания.

Каждый общий локальный образ собирает одна служба: airflow-init владеет сборкой образа Airflow, superset-init — образа Superset. Зависимые процессы только используют готовый образ. docker compose up --build собирает образы до запуска контейнеров; повторять build у каждого процесса не нужно, а Buildx 0.30.1 при параллельном экспорте одного тега иногда отвечает image already exists.

Для входа выбран SimpleAuthManager. У него нет команды создания пользователя, поэтому airflow-init записывает пароль администратора из окружения в JSON-файл отдельного тома airflow_auth. Новый именованный том принадлежит root, а Airflow работает от пользователя airflow. Поэтому airflow-init запускается от root, назначает владельца каталога и сразу выполняет Python и команды Airflow через runuser от пользователя airflow. Все файлы репозитория подключены к этому контейнеру только для чтения. JWT-секрет, ключ подписи ссылок на журналы и ключ Fernet одинаковы для всех процессов и приходят из окружения.

Один Postgres 16 хранит две базы метаданных. У Airflow и Superset разные базы, пользователи и строки подключения. Это экономит один контейнер, но сохраняет границу владения данными.

Airflow получает два подготовленных подключения к clickhouse-01: рабочее clickhouse_default и административное clickhouse_lifecycle для дагов жизненного цикла мира (ADR 0013). Оба имеют тип clickhouse, который регистрирует официальный провайдер apache-airflow-providers-clickhousedb. SQL-файлы исполняет общий SQLExecuteQueryOperator, а программные запросы идут через ClickHouseHook. Сам провайдер работает через clickhouse-connect; его версия закреплена отдельно, чтобы сборка не меняла транспорт незаметно.

Superset получает подключение clickhousedb:// к clickhouse-02. Пробник Airflow создаёт служебные таблицы ON CLUSTER, пишет на первой ноде и через remote читает Distributed на второй. Разные ноды сохраняют учебную ловушку: забытый ON CLUSTER проявится в Superset, даже если операция Airflow на первой ноде прошла успешно.

Клиент Kafka также добавлен прямо в образ Airflow. Официальный провайдер использует тот же confluent-kafka, а пробнику не нужны его подключение, операторы и обёртки. Топик пробника постоянный, сообщение каждого запуска отличается уникальным маркером.

Superset собирается от apache/superset:6.1.0. В образ добавлены clickhouse-connect для ClickHouse и psycopg2-binary для метаданных Postgres. Подключение ClickHouse импортируется из YAML при подготовке.

Prometheus читает встроенные точки метрик двух серверов ClickHouse и keeper. Отдельные сборщики не нужны. Grafana получает источник Prometheus из файла.

Почему

Разделение Airflow показывает архитектуру третьей версии и даёт честные проверки здоровья процессов. LocalExecutor достаточен для одного учебного компьютера. Отказ от triggerer, второго Postgres и внешних сборщиков удерживает стенд в пределе 3,4 ГБ.

Ресурсный довод предыдущего абзаца отозван ADR 0004: предела 3,4 ГБ у стенда нет, вместо него объявлено требование к машине. Сами решения остаются в силе по остальным основаниям, названным выше. Отказ от внешних сборщиков вдобавок частично пересмотрен ADR 0002: сборщик метрик Kafka нужен ради отставания чтения.

Тома clickhouse_*_data хранят данные keeper и двух нод ClickHouse. kafka_data, postgres_metadata_data, superset_home, prometheus_data и grafana_data хранят состояние своих сервисов. airflow_logs хранит журналы, а airflow_auth — JSON-файл с учебным паролем администратора. Каталог dags/ и все файлы настройки подключены только для чтения, поэтому контейнеры не меняют рабочее дерево.

Что проверено

Исследование задачи сверило через Context7 публичный API DAG с Task SDK Airflow и аргумент schedule. Решение дополнительно проверено по документации Airflow 3.3.0: публичный интерфейс, архитектура процессов, SimpleAuthManager и API здоровья. Оттуда взяты airflow.sdk, обязательный отдельный обработчик DAG, возможность не запускать triggerer и проверка конкретных компонентов здоровья.

Для ClickHouse через Context7 и официальную документацию Airflow проверены ClickHouseHook, тип подключения clickhouse и работа SQLExecuteQueryOperator с SQL-файлом, параметрами и несколькими выражениями. Закреплён apache-airflow-providers-clickhousedb==1.0.0: на 21 августа 2026 года это последний стабильный выпуск; 1.0.1 опубликован только как предварительная версия. Зависимость провайдера допускает любой clickhouse-connect>=1.3.0, поэтому прежний clickhouse-connect==1.6.0 оставлен прямой зависимостью образа.

Для Kafka проверен состав официального провайдера. Выбран прямой confluent-kafka: провайдер строит свои подключения и обёртки поверх него, которые двум коротким пробникам не нужны.

Драйверы и строки подключения проверены по документации Superset 6.1.0: подключения к базам, ClickHouse и база метаданных. Форма декларативного импорта и команда test-db проверены по исходному коду Superset 6.1.0 и на запущенном образе. Конфигурация метрик проверена по файлам закреплённого образа ClickHouse 26.3.17.56 и на живых точках серверов и keeper.