docs(readme): корневой README переписан под менти и песочницу

- Зачем:
  - стенд теперь учебный (для менти и для экспериментов), рекрутерская
    рамка 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 и
    рабочие ссылки на профильные доки.
This commit is contained in:
2026-06-06 20:11:38 +03:00
parent d4e6d84524
commit ce7f03be28
+62 -297
View File
@@ -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) — задание, из которого вырос стенд.