# Учебная дата-платформа кликстрима Стенд для работы с кликстримом. Преемник учебного стенда [clickstream-ch-kafka-superset-demo](https://git.dementev.space/ddmitry/clickstream-ch-kafka-superset-demo). ## Статус Репозиторий строится по спеке [«Боевой реализм стенда (v2)»](docs/specs/2026-07-30-stand-v2-realism.md). Сейчас работают кластер ClickHouse из двух шардов, отдельный clickhouse-keeper, односерверная Kafka в режиме KRaft, Airflow 3.3, Superset, Prometheus, Grafana и общая база Postgres для метаданных. ## Быстрый старт Нужны Docker с Compose. Полная проверка также использует `curl`, `jq`, `awk`, `grep`, `sed`, `tail`, `sleep` и `timeout`. По умолчанию должны быть свободны порты `23000`, `28080`, `28088`, `28123`, `28124`, `29000`, `29001`, `29090` и `29092`. Для статической проверки `make config-test` нужен `uv`. Стенд запускается без `.env`: ```bash make up make smoke ``` Чтобы изменить образы, порты или учебные учётные данные, скопируйте образец: ```bash cp .env.example .env make up make smoke ``` Учётные данные Postgres и Grafana применяются при создании их томов. После первого запуска меняйте их только вместе с `make clean`: команда удалит все локальные данные стенда, а следующий `make up` создаст их с новыми значениями. `make up` собирает локальный образ Superset, поднимает весь стенд и ждёт здорового состояния долгоживущих контейнеров. Одноразовые `airflow-init` и `superset-init` завершаются с кодом 0. Первый обновляет схему Airflow, подготавливает администратора и подключение к `clickhouse-01`. Второй обновляет Superset, создаёт администратора и импортирует подключение к `clickhouse-02`. `make smoke` проверяет согласованность `.env.example` с Compose, зависимости машины, здоровье контейнеров, Kafka через порт машины, три цели Prometheus, источник Grafana, компоненты Airflow, ручной запуск примера DAG, метаданные и подключение Superset. В конце проверка ждёт 20 секунд покоя, печатает общую память контейнеров и падает при превышении 3,4 ГБ. Временный топик Kafka и проверочный запуск DAG удаляются. `make smoke-cluster` запускает отдельную глубокую проверку ClickHouse: описание кластера, макросы, связь с keeper, `ReplicatedMergeTree`, `Distributed`, очередь распределённых DDL и очистку временных таблиц. `make config-test` проверяет Compose, синтаксис Bash и Python и пробельные ошибки в diff без запуска стенда. `make smoke-guards` сначала проверяет аварийную семантику кластерной проверки, а затем останавливает Prometheus и убеждается, что общая проверка называет его и завершается с ошибкой. В конце стенд восстанавливается. Остановить контейнеры без удаления данных можно командой `make down`. Для полного сброса с удалением всех именованных томов используйте `make clean`. Повторный `make up` безопасен: одноразовая подготовка приложений идемпотентна. ## Состав и доступ - `clickhouse-01` — инициатор DDL и точка подключения Airflow; - `clickhouse-02` — точка подключения Superset; - `clickhouse-keeper` — координатор кластера; - `kafka` — один брокер KRaft; - `postgres-metadata` — один Postgres с отдельными базами и пользователями `airflow` и `superset`; - `airflow-apiserver`, `airflow-scheduler` и `airflow-dag-processor` — Airflow 3.3 с LocalExecutor, без triggerer; - `superset` — интерфейс и подготовленное подключение ClickHouse; - `prometheus` и `grafana` — сбор и просмотр встроенных метрик ClickHouse. Порты доступны только с локальной машины: - нода 1 — `http://127.0.0.1:28123`, нативный порт `29000`; - нода 2 — `http://127.0.0.1:28124`, нативный порт `29001`; - Kafka — `127.0.0.1:29092`; - Airflow — `http://127.0.0.1:28080`, пользователь `admin`, пароль `airflow`; - Superset — `http://127.0.0.1:28088`, пользователь `admin`, пароль `superset`; - Prometheus — `http://127.0.0.1:29090`; - Grafana — `http://127.0.0.1:23000`, пользователь `admin`, пароль `admin`. У локального учебного кластера нет пароля: ноды используют общего пользователя `default` для запросов `Distributed`. Порты поэтому привязаны к `127.0.0.1` и не открыты во внешнюю сеть. Пароли интерфейсов, пароли Postgres, ключи Airflow и Superset, отсутствие пароля ClickHouse и отсутствие проверки доступа у Kafka и Prometheus — намеренно простые и явно ненастоящие настройки локального учебного стенда. Это не пример настройки защиты: не копируйте значения из `.env.example` в рабочую среду. Все опубликованные порты привязаны только к `127.0.0.1`; Postgres наружу не опубликован. В бою перед репликами ClickHouse обычно был бы балансировщик. Здесь в каждом шарде одна реплика, поэтому балансировать нечего. Балансировщик и топология 2×2 намеренно не входят в стенд. Конфигурация сверена 30 июля 2026 года с официальной документацией ClickHouse: [настройками сервера](https://clickhouse.com/docs/operations/server-configuration-parameters/settings), [Keeper](https://clickhouse.com/docs/guides/oss/deployment-and-scaling/keeper/), [ReplicatedMergeTree](https://clickhouse.com/docs/engines/table-engines/mergetree-family/replication), [ON CLUSTER](https://clickhouse.com/docs/sql-reference/distributed-ddl) и [Distributed](https://clickhouse.com/docs/engines/table-engines/special/distributed). Описание кластера задаётся через `remote_servers`, макросы — через `macros`, подключение к keeper — через `zookeeper`; путь `ReplicatedMergeTree` содержит `{shard}` и `{replica}`, а `Distributed` получает имя кластера, базу, локальную таблицу и ключ шардирования. Макросы выбраны, чтобы один DDL через `ON CLUSTER` создавал отдельный путь каждого шарда без вписанных вручную значений. Для образа зафиксирован точный текущий [LTS-выпуск 26.3.17.56](https://github.com/ClickHouse/ClickHouse/releases/tag/v26.3.17.56-lts); серверы и keeper используют один образ. Настройки Kafka 4.3.1 сверены с [примером односерверного KRaft](https://github.com/apache/kafka/blob/4.3.1/docker/examples/docker-compose-files/single-node/plaintext/docker-compose.yml). Секция метрик взята из конфигурации закреплённого образа ClickHouse и проверена на серверах и keeper. Подготовка источника Grafana сверена с [официальным описанием автоматической настройки](https://grafana.com/docs/grafana/latest/administration/provisioning/). Prometheus собирает только встроенные метрики двух серверов и keeper; внешних сборщиков, панелей и правил оповещения пока нет. После изменения `infra/clickhouse/config.d/prometheus.xml` выполните `docker compose restart clickhouse-01 clickhouse-02`: обычный `make up` не перезапускает уже созданные серверы и они продолжают работать со старой конфигурацией. Airflow закреплён на 3.3.0. Состав обязательных процессов, LocalExecutor, публичный `airflow.sdk`, API здоровья и SimpleAuthManager сверены с [архитектурой Airflow 3.3](https://airflow.apache.org/docs/apache-airflow/3.3.0/core-concepts/overview.html), [публичным интерфейсом](https://airflow.apache.org/docs/apache-airflow/3.3.0/public-airflow-interface.html) и [описанием здоровья](https://airflow.apache.org/docs/apache-airflow/3.3.0/administration-and-deployment/logging-monitoring/check-health.html). Superset закреплён на 6.1.0; драйвер `clickhouse-connect`, форма `clickhousedb://` и драйвер Postgres сверены с [документацией подключений Superset](https://superset.apache.org/user-docs/6.1.0/databases/) и [настройкой базы метаданных](https://superset.apache.org/admin-docs/6.1.0/configuration/configuring-superset/). ## Что здесь будет - одно широкое событие кликстрима по образцу выгрузки Яндекс Метрики вместо четырёх топиков; - второй источник — заказы бэкенда, ежедневным слепком в ту же Kafka; - сверка клиентской покупки с заказом бэкенда: деньги считаем по бэкенду, поведение и атрибуцию — по трекеру; - анонимный кликстрим и склейка кука↔пользователь через покупки; - ClickHouse кластером как единственным режимом. ## Чем отличается от предшественника Предшественник остаётся стабильным учебным стендом и заморожен для новых фич: там событие разрезано на четыре топика, есть только просмотры страниц, посетители опознаны по email, ClickHouse — одна нода. Развитие идёт здесь. ## Документация - [docs/specs/](docs/specs/) — спеки: источник истины о задуманном. - [docs/research/](docs/research/) — исследования; сейчас это формат кликстрима Яндекса, по которому строится модель события. - [AGENTS.md](AGENTS.md) — контракт работы в репозитории.