From ce7f03be28c92dda29e4e40be483452b07b59ff4 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Sat, 6 Jun 2026 20:11:38 +0300 Subject: [PATCH] =?UTF-8?q?docs(readme):=20=D0=BA=D0=BE=D1=80=D0=BD=D0=B5?= =?UTF-8?q?=D0=B2=D0=BE=D0=B9=20README=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=B0=D0=BD=20=D0=BF=D0=BE=D0=B4=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B8=20=D0=B8=20=D0=BF=D0=B5=D1=81=D0=BE=D1=87?= =?UTF-8?q?=D0=BD=D0=B8=D1=86=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - стенд теперь учебный (для менти и для экспериментов), рекрутерская рамка DE-задания неактуальна и сбивала читателя; README дублировал профильные доки и расходился с ними. - Что: - README сделан тонким указателем на три двери: курс, быстрый старт, устройство стенда; объём сокращён с 361 до 96 строк. - быстрый старт переведён на основной Airflow-путь (ddl_init → kafka_load → etl_pipeline) вместо legacy make-пути. - срезаны дубли (DBeaver, структура дашборда, мониторинг, troubleshooting, Makefile, дерево проекта, «Статус/В планах») с уводом в OPERATIONS, ARCHITECTURE, REPO_MAP, SUPERSET_DASHBOARD. - исправлен URL дашборда Superset на slug ecommerce-analytics; убран фейковый бейдж лицензии. - Проверка: - открыть README.md, пройти быстрый старт, проверить рендер mermaid и рабочие ссылки на профильные доки. --- README.md | 359 ++++++++++-------------------------------------------- 1 file changed, 62 insertions(+), 297 deletions(-) diff --git a/README.md b/README.md index 6a86310..63e2f85 100644 --- a/README.md +++ b/README.md @@ -1,109 +1,85 @@ -# ClickHouse Mini DWH для кликстрима +# Учебный стенд DWH кликстрима [![Stack](https://img.shields.io/badge/stack-Kafka%20%7C%20ClickHouse%20%7C%20Airflow%20%7C%20Superset%20%7C%20Prometheus%2FGrafana-blue)](./docker-compose.yml) [![Layers](https://img.shields.io/badge/layers-STG%20→%20ODS%20→%20DDS%20→%20DM-green)](./docs/ARCHITECTURE.md) -[![License](https://img.shields.io/badge/license-Educational-orange)]() -Мини-демо для решения задания [DE-task.md](./docs/DE-task.md): развернуть инфраструктуру на своей машине, прогнать кликстрим через Kafka в ClickHouse, сделать регулярный расчёт в Airflow и подготовить витрины под дашборд. +Живой стек для работы с кликстримом: Kafka, ClickHouse, Airflow, Superset и мониторинг +(Prometheus с Grafana) поднимаются в Docker одной командой. На этом стенде можно учиться +по курсу или просто поднять его у себя и поэкспериментировать с потоковой загрузкой и +витринами. -Фокус проекта: быстро показать работающий end-to-end сценарий и понятным языком объяснить, как устроены слои и почему пайплайн не падает на "грязных" данных. +Поток данных коротко: +`data/*.jsonl → Airflow (kafka_load) → Kafka → ClickHouse (слой STG) → Airflow +(etl_pipeline: STG → ODS → DDS → DM) → Superset`. -Коротко про поток: -`data/*.jsonl` -> Airflow DAG `kafka_load` -> Kafka (1 строка = 1 сообщение) -> ClickHouse `stg` (сырые JSON) -> Airflow DAG `etl_pipeline` (`stg -> ods -> dds -> dm`) -> Superset. +## Куда дальше ---- +- **Хочешь учиться** — открой [курс «Кликстрим на ClickHouse»](./docs/course/README.md). + Это продвинутый курс «со звёздочкой»: основные приёмы инженерии данных проходишь прямо + на этом стенде. +- **Хочешь поднять и попробовать** — следуй быстрому старту ниже. +- **Хочешь разобраться в устройстве** — смотри [архитектуру слоёв](./docs/ARCHITECTURE.md), + [запуск и эксплуатацию](./docs/OPERATIONS.md) и [карту репозитория](./docs/REPO_MAP.md). -## Быстрый старт (демо-сценарий) +## Быстрый старт + +Стенд управляется через Airflow — это основной рабочий способ. Отдельные shell-скрипты в +`scripts/` оставлены как запасной вариант для локальных прогонов (см. +[OPERATIONS](./docs/OPERATIONS.md)). ```bash -# 1) Поднять инфраструктуру +# 1. Поднять весь стек make up - -# Проверить статусы контейнеров -docker compose ps +docker compose ps # убедиться, что контейнеры запустились ``` -Дальше основной путь идёт через Airflow (как в задании). +Дальше — три шага в Airflow (веб-интерфейс `http://localhost:8080`, логин и пароль +`admin`/`admin`). Сними каждый DAG с паузы (кнопка Unpause) и запусти по очереди: -1. Открыть Airflow UI: `http://localhost:8080` (admin/admin) -2. Включить (unpause) и запустить `ddl_init` (создаёт базы/таблицы/VIEW в ClickHouse) +1. `ddl_init` — создаёт базы, таблицы и представления в ClickHouse. +2. `kafka_load` — заливает события из `data/*.jsonl` в Kafka. +3. `etl_pipeline` — прогоняет цепочку STG → ODS → DDS → DM. + +Те же шаги можно запускать из командной строки — это удобно для скриптов: -Опционально можно триггернуть DAG из CLI (удобно для CI/скрипта): ```bash docker compose exec -T airflow-webserver airflow dags trigger ddl_init -``` -Загрузка данных в Kafka через Airflow DAG: -```bash -# Полная загрузка (по умолчанию limit=0) -docker compose exec -T airflow-webserver airflow dags trigger kafka_load \ - --conf '{"reset_topics": true}' - -# Ограниченная загрузка — первые 100 строк +# Загрузить первые 100 строк каждого файла (limit=0 — загрузить всё) docker compose exec -T airflow-webserver airflow dags trigger kafka_load \ --conf '{"limit": 100, "reset_topics": true}' -``` -Запуск batch-трансформации (STG -> ODS -> DDS -> DM) в Airflow (если DAG выключен, сначала unpause): -```bash docker compose exec -T airflow-webserver airflow dags trigger etl_pipeline \ --conf '{"full_refresh": true}' ``` -Smoke-check результата в ClickHouse: +Проверить, что данные дошли до витрин: + ```bash -docker compose exec -T clickhouse clickhouse-client --user=default --password=123456 --query \ - "SELECT 'ods.browser_event' AS t, count() AS rows FROM ods.browser_event" -docker compose exec -T clickhouse clickhouse-client --user=default --password=123456 --query \ - "SELECT 'dds.click' AS t, count() AS rows FROM dds.click" -docker compose exec -T clickhouse clickhouse-client --user=default --password=123456 --query \ - "SELECT 'dds.event' AS t, count() AS rows FROM dds.event" -docker compose exec -T clickhouse clickhouse-client --user=default --password=123456 --query \ - "SELECT 'dm.dq_summary' AS t, count() AS rows FROM dm.dq_summary" +docker compose exec -T clickhouse clickhouse-client --user=default --password=123456 \ + --query "SELECT count() FROM dm.v_events_enriched" ``` ---- +Подробный сценарий запуска, параметры DAG-ов и разбор частых проблем — в +[OPERATIONS](./docs/OPERATIONS.md). -## Доступные сервисы +## Сервисы и доступы -| Сервис | URL | Назначение | Логин/Пароль | -|--------|-----|------------|--------------| -| ClickHouse HTTP | http://localhost:9123/play | SQL-запросы | default/123456 | -| Kafka UI | http://localhost:8082 | Просмотр топиков | — | -| Airflow | http://localhost:8080 | Оркестрация ETL | admin/admin | -| Superset | http://localhost:8088 | BI-дашборды | admin/admin | -| Prometheus | http://localhost:9090 | Метрики | — | -| Grafana | http://localhost:3000 | Визуализация метрик | admin/admin | +| Сервис | Адрес | Назначение | Логин/пароль | +|--------|-------|------------|--------------| +| Airflow | `http://localhost:8080` | оркестрация ETL | admin/admin | +| ClickHouse | `http://localhost:9123/play` | SQL-запросы | default/123456 | +| Kafka UI | `http://localhost:8082` | просмотр топиков | — | +| Superset | `http://localhost:8088` | дашборды | admin/admin | +| Prometheus | `http://localhost:9090` | метрики | — | +| Grafana | `http://localhost:3000` | графики метрик | admin/admin | -Superset: UI доступен после `make up` по адресу http://localhost:8088, дашборд — http://localhost:8088/superset/dashboard/1/ +Готовый дашборд в Superset: +`http://localhost:8088/superset/dashboard/ecommerce-analytics/` — он создаётся +автоматически через минуту-две после `make up`. Состав и настройка дашборда описаны в +[SUPERSET_DASHBOARD](./docs/SUPERSET_DASHBOARD.md). ---- - -## Подключение DBeaver (кратко) - -После прогона `ddl_init -> kafka_load -> etl_pipeline` можно быстро проверить витрины в DBeaver (удобно для демо бизнесу). - -1. `Database -> New Database Connection -> ClickHouse` -2. Параметры: - - `Host`: `localhost` - - `Port`: `9123` (HTTP) - - `Database`: `default` - - `Username`: `default` - - `Password`: `123456` -3. Нажать `Test Connection` -> `Finish` - -Если ваш драйвер просит native-протокол, используйте порт `8002`. - -Полезные быстрые запросы для первичного анализа: -```sql -SELECT count() AS rows FROM dm.v_events_enriched; -SELECT * FROM dm.v_daily_traffic ORDER BY event_date DESC LIMIT 20; -SELECT * FROM dm.v_utm_effectiveness ORDER BY clicks DESC LIMIT 20; -``` - ---- - -## Архитектура (в двух словах) +## Как устроен поток данных ```mermaid flowchart LR @@ -131,230 +107,19 @@ flowchart LR D3 -.->|batch| ODS & DDS ``` -Особенность задания про "грязные данные": парсинг не валит pipeline, ошибки фиксируются в `ods.*_errors` и в поле `parse_errors`. +«Грязные» записи не роняют пайплайн: ошибки разбора складываются в `ods.*_errors` и в +поле `parse_errors`, а обработка продолжается. -[Подробное описание архитектуры →](./docs/ARCHITECTURE.md) - ---- - -## Структура проекта - -``` -. -├── sql/ -│ ├── ddl/ # DDL по слоям -│ │ ├── 00_databases.sql -│ │ ├── stg/10_stg.sql -│ │ ├── ods/20_ods.sql -│ │ ├── dds/30_dds.sql -│ │ └── dm/40_dm.sql -│ ├── ods/ # Batch SQL: STG -> ODS -│ ├── dds/ # Batch SQL: ODS -> DDS -│ └── dm/ # Batch SQL: DDS -> DM -├── configs/ # Конфигурации сервисов -│ ├── superset_config.py # Конфиг Superset (PostgreSQL metadata) -│ ├── prometheus/ # Prometheus конфигурация -│ └── grafana/ # Grafana dashboards & datasources -├── scripts/ # Служебные shell-скрипты (legacy fallback, не основной путь) -├── airflow/ # Конфигурация Airflow -│ ├── dags/ # Airflow DAGs для оркестрации -│ └── requirements.txt -├── superset/ # Скрипты инициализации Superset -│ ├── init_superset.py # Подключение к ClickHouse + датасеты -│ └── create_dashboard.py # Создание дашборда с чартами -├── docs/ # Документация -│ └── ARCHITECTURE.md # Подробное описание слоёв -├── data/ # Исходные JSONL файлы -├── docker-compose.yml -└── Makefile # Команды: up, ddl, transform, superset-* -``` - ---- - -## Команды Makefile - -| Команда | Описание | -|---------|----------| -| `make up` | Поднять инфраструктуру | -| `make ddl` | Применить DDL в ClickHouse (вне Airflow) | -| `make transform` | Запустить batch-процесс `STG -> ODS -> DDS -> DM` (вне Airflow) | -| `make superset-init` | Подключение к ClickHouse + импорт датасетов | -| `make superset-dashboard` | Создание дашборда с чартами, обновление layout/metadata | -| `make superset-ui` | Показать URL Superset | -| `make superset-restart` | Перезапуск Superset | - -Примечания про сохранность данных: -- Данные ClickHouse сохраняются в Docker volume `clickhouse-data`. -- Данные Kafka сохраняются в Docker volume `kafka-data`. -- `docker compose down` сохраняет named volumes, `docker compose down -v` удаляет их (и данные пропадут). - ---- - -## Ключи данных (как джойним) - -```mermaid -flowchart LR - subgraph Sources["Источники"] - BE["browser_events (event_id, click_id)"] - LE["location_events (event_id)"] - DE["device_events (click_id)"] - GE["geo_events (click_id)"] - end - - subgraph DDS["DDS"] - EV["event (event_id PK)"] - CL["click (click_id PK)"] - end - - subgraph DM["DM"] - V1[v_events_enriched] - V2[v_daily_traffic] - V3[v_utm_effectiveness] - end - - BE -->|event_id| EV - LE -->|event_id| EV - BE -->|click_id| CL - DE -->|click_id| CL - GE -->|click_id| CL - - EV -->|LEFT JOIN click_id| V1 - CL --> V1 - EV --> V2 & V3 - CL --> V2 & V3 -``` - ---- - -## Дашборд в Superset (опционально, но полезно) - -Superset развёрнут с автоматической инициализацией: подключение к ClickHouse, датасеты и дашборд создаются автоматически при первом запуске. - -### Быстрый доступ - -| URL | Назначение | Логин/Пароль | -|-----|------------|--------------| -| http://localhost:8088 | Superset UI | admin/admin | -| http://localhost:8088/superset/dashboard/1/ | Готовый дашборд | — | - -### Автоматическая инициализация (рекомендуется) - -```bash -# При первом запуске инфраструктуры -make up - -# Дашборд создаётся автоматически через 30-60 секунд -# Проверить готовность: -curl http://localhost:8088/health # должно вернуть 200 -``` - -Что создаётся автоматически: -- **Подключение к ClickHouse**: `clickhouse_dwh` (URI: `clickhousedb://default:123456@clickhouse:8123/default`) -- **Датасеты** (6 шт.): `v_events_enriched`, `v_daily_traffic`, `v_utm_effectiveness`, `v_top_pages_daily`, `v_session_overview`, `dq_summary` -- **Чарты** (10 шт.): KPI метрики, графики трафика, география, UTM-эффективность, прохождение строк по слоям -- **Дашборд**: "🛒 E-commerce Analytics Dashboard" - -### Ручная инициализация (если автоматика не сработала) - -```bash -# Подключение к ClickHouse + датасеты -make superset-init - -# Создание дашборда с чартами -make superset-dashboard -``` - -### Структура дашборда - -Дашборд "E-commerce Analytics Dashboard" включает: - -| Блок | Чарты | Датасет | -|------|-------|---------| -| **KPI** | Total Events, Unique Users, Avg Events/Visit, Conversion to /confirmation | `v_events_enriched` | -| **Динамика** | Events over Time (timeline), Traffic by Device (pie) | `v_events_enriched` | -| **География** | Geography Map по странам | `v_events_enriched` | -| **Маркетинг** | UTM Effectiveness Table, Page Funnel | `v_utm_effectiveness`, `v_top_pages_daily` | -| **Слои** | Rows by Layer (event) — прохождение строк STG→ODS→DDS→DM | `dq_summary` | - -Фильтр `Date Range` по умолчанию открыт как `No filter`, потому что демо-данные лежат в -историческом диапазоне (`2022-11-28`). - -Фильтры Superset задаются в левой панели dashboard. Click-to-filter по виджетам не включен: -клики по pie chart, карте, таблице или funnel не меняют другие charts. `Country`, -`Device Type` и `Browser` применяются к charts на `dm.v_events_enriched`; `Date Range` -работает с charts, где есть `event_date`. - -### Архитектура Superset - -``` -┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ -│ Superset UI │────▶│ PostgreSQL │───▶│ ClickHouse │ -│ (localhost) │ │ (metadata) │ │ (данные) │ -│ :8088 │ │ dashboards, │ │ dm.v_* VIEW │ -└─────────────────┘ │ datasets, charts│ └─────────────────┘ - └──────────────────┘ -``` - -Особенности конфигурации: -- **Metadata**: PostgreSQL (shared с Airflow) — данные сохраняются при перезапуске -- **Data**: ClickHouse через `clickhouse-connect` (HTTP порт 8123) -- **Config**: `configs/superset_config.py` (PostgreSQL URI, секретный ключ) - ---- - -## Мониторинг инфраструктуры (Grafana + Prometheus) - -Для оценки состояния ClickHouse доступен дашборд мониторинга: - -1. Открыть Grafana: `http://localhost:3000` (admin/admin) -2. Дашборд "ClickHouse Overview" загружается автоматически -3. Проверить метрики Prometheus: `http://localhost:9090` → Status → Targets - -Что отслеживается: -- System Health: CPU, Memory (Resident/Code) -- Query Performance: queries/sec, active queries, failed queries -- MergeTree Storage: parts count, merge rate - -Что алертится: -- Failed queries rate (`rate(ClickHouseProfileEvents_FailedQuery[5m]) > 0`) -- Memory Resident > 85% от `OSMemoryTotal` -- Active parts > 500 - -Конфигурация provisioning находится в [`configs/grafana/provisioning/`](configs/grafana/provisioning/). Подробнее в [`docs/OPERATIONS.md`](docs/OPERATIONS.md#мониторинг). - ---- - -## Частые проблемы - -- `etl_pipeline` падает с сообщением про схему: сначала запустите `ddl_init`. -- После `docker compose down -v` схема и данные исчезнут: нужно заново запустить `ddl_init`, затем `kafka_load`, затем `etl_pipeline`. -- Подключения используют разные протоколы: - - Airflow (ClickHouseOperator) ходит в ClickHouse по native TCP (порт `9000` внутри сети Docker). - - Superset (clickhouse-connect) ходит по HTTP (порт `8123` внутри сети Docker). -- **Superset**: дашборд не появился сразу — подождите 30-60 секунд после `make up`, затем проверьте `curl http://localhost:8088/health`. -- **Superset**: после `make clean` витрины `dm.*` ещё не созданы, поэтому чарты могут быть пустыми до запуска `ddl_init -> kafka_load -> etl_pipeline`; после этого выполните `make superset-init`. -- **Superset**: при полном сбросе (`docker compose down -v`) метаданные Superset пропадут т.к. используется общая PostgreSQL. Для чистого перезапуска Superset удалите только БД `superset` в PostgreSQL и перезапустите контейнеры. - ---- - -## Статус проекта - -Реализовано: -- **Инфраструктура**: Kafka + ClickHouse + Airflow + Superset + Prometheus/Grafana -- **Ingest**: DAG `ddl_init` (DDL + проверка схемы), DAG `kafka_load` (параметры `limit`, `reset_topics`) -- **Трансформации**: DAG `etl_pipeline` (pre-check, batch STG→ODS→DDS→DM, валидация) -- **Витрины**: VIEW в DM для бизнес-дашбордов (трафик, UTM, качество данных) -- **Superset**: Автоматическая инициализация (подключение ClickHouse, 6 датасетов, 10 чартов, дашборд), метаданные в PostgreSQL -- **Надёжность**: ошибки парсинга сохраняются в ODS, пайплайн не падает на "грязных" данных -- **Мониторинг**: Prometheus скрейпит ClickHouse метрики, Grafana дашборд и alert rules - -В планах (не требуется для MVP задания): -- Инкрементальный batch (watermark вместо `full_refresh`) -- DQ мониторинг по расписанию - ---- +Подробное описание слоёв STG/ODS/DDS/DM, диаграммы и обоснование решений — +в [ARCHITECTURE](./docs/ARCHITECTURE.md). ## Документация -- [Архитектура и слои](./docs/ARCHITECTURE.md) — подробное описание STG/ODS/DDS/DM, ER-диаграммы, обоснование решений -- [DE-task.md](./docs/DE-task.md) — исходное задание +- [Архитектура и слои](./docs/ARCHITECTURE.md) — устройство STG/ODS/DDS/DM, диаграммы, + обоснование решений. +- [Запуск и эксплуатация](./docs/OPERATIONS.md) — сценарий запуска, параметры DAG-ов, + мониторинг, частые проблемы. +- [Карта репозитория](./docs/REPO_MAP.md) — где какие файлы и что менять. +- [Курс «Кликстрим на ClickHouse»](./docs/course/README.md) — учебная программа на этом + стенде. +- [DE-task.md](./docs/DE-task.md) — задание, из которого вырос стенд.