Зачем. Демонстрационный DAG example_clickstream_hello ничего не проверял: он не обращался ни к ClickHouse, ни к Kafka, поэтому его зелёный результат ничего не говорил о стенде. Пробники проверяют связи по-настоящему — и тем же клиентом, каким будут ходить рабочие DAG. Что. - test_clickhouse: пишет строку в ReplicatedMergeTree на ноде 1 и читает её с ноды 2 через Distributed. Данные проходят путь «нода 2 → все шарды → шард ноды 1», то есть проверяется межшардовое чтение, а не одна нода. - test_kafka: пишет в постоянный топик сообщение с меткой прогона и вычитывает его обратно. - infra/airflow/Dockerfile: clickhouse-connect 1.6.0 и confluent-kafka 2.15.0 вшиты в образ, импорт проверяется на сборке — при запуске контейнера пакеты не доустанавливаются. - Проверки: scripts/stand-smoke.sh гоняет оба пробника через API Airflow, scripts/config-test.sh разбирает DAG без стенда, tests/stand-smoke-guards.sh проверяет красный путь, tests/dag-probes-unit.py — модульные проверки разбора. - README и ADR 0001 обновлены тем же изменением. - Удалён dags/example_clickstream_hello.py. Проверка. make config-test — пройдено 3, 3 и 6, ошибок 0. make clean; cp .env.example .env; make up — 116 с на чистых томах. make smoke — пройдено 25, ошибок 0; стенд занимает 2244,0 MiB. make smoke-cluster — все 8 проверок кластера. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
173 lines
13 KiB
Markdown
173 lines
13 KiB
Markdown
# Учебная дата-платформа кликстрима
|
||
|
||
Стенд для работы с кликстримом. Преемник учебного стенда
|
||
[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` собирает локальные образы Airflow и Superset, поднимает весь стенд и
|
||
ждёт здорового состояния долгоживущих контейнеров. В образ Airflow добавлены
|
||
закреплённые клиенты ClickHouse и Kafka. Одноразовые `airflow-init` и
|
||
`superset-init` завершаются с кодом 0. Первый обновляет схему Airflow,
|
||
подготавливает администратора и подключение к `clickhouse-01`. Второй обновляет
|
||
Superset, создаёт администратора и импортирует подключение к `clickhouse-02`.
|
||
|
||
`make smoke` проверяет согласованность `.env.example` с Compose, зависимости
|
||
машины, здоровье контейнеров, Kafka через порт машины, три цели Prometheus,
|
||
источник Grafana, компоненты Airflow, ручной запуск пробников `test_clickhouse`
|
||
и `test_kafka`, метаданные и подключение Superset. Первый пробник создаёт
|
||
таблицы на обеих нодах и читает через `Distributed` на ноде 2 строку из
|
||
локальной таблицы ноды 1. Второй пишет в Kafka и читает свой маркер. В конце
|
||
проверка ждёт 20 секунд покоя, печатает общую память контейнеров и падает при
|
||
превышении 3,4 ГБ. Временный топик проверки с машины и запуски DAG удаляются;
|
||
постоянный топик пробника сохраняется, а старые записи чистит Kafka.
|
||
|
||
`make smoke-cluster` запускает отдельную глубокую проверку ClickHouse: описание
|
||
кластера, макросы, связь с keeper, `ReplicatedMergeTree`, `Distributed`, очередь
|
||
распределённых DDL и очистку временных таблиц.
|
||
|
||
`make config-test` проверяет Compose, синтаксис Bash и Python, малые проверки
|
||
логики пробников и пробельные ошибки в diff без запуска стенда.
|
||
|
||
`make smoke-guards` сначала проверяет аварийную семантику кластерной проверки,
|
||
а затем удаляет служебную таблицу пробника только на второй ноде и
|
||
останавливает Prometheus с Kafka. Общая проверка должна назвать 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).
|
||
Для пробников проверены публичный `Connection.get` из `airflow.sdk` и клиент
|
||
`clickhouse-connect`. Официальный провайдер Kafka сам использует
|
||
`confluent-kafka`; отдельное подключение и обёртки провайдера здесь не нужны,
|
||
поэтому прямой клиент оставляет образ и пример короче.
|
||
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) — контракт работы в репозитории.
|