diff --git a/docs/DEMO_CHEATSHEET_5MIN.md b/docs/DEMO_CHEATSHEET_5MIN.md deleted file mode 100644 index 12ab372..0000000 --- a/docs/DEMO_CHEATSHEET_5MIN.md +++ /dev/null @@ -1,114 +0,0 @@ -# Шпаргалка для 5-минутного демо проекта - -Цель: за 5 минут показать работодателю рабочий end-to-end пайплайн и инженерный уровень исполнения. - ---- - -## 0) Подготовка до звонка (1 раз) - -```bash -make up -docker compose exec -T airflow-webserver airflow dags trigger ddl_init -docker compose exec -T airflow-webserver airflow dags trigger kafka_load --conf '{"limit": 50, "reset_topics": true}' -docker compose exec -T airflow-webserver airflow dags trigger etl_pipeline --conf '{"full_refresh": true}' -``` - -Проверить доступы: -- Airflow: `http://localhost:8080` (`admin/admin`) -- Kafka UI: `http://localhost:8082` -- ClickHouse Play: `http://localhost:9123/play` -- Grafana: `http://localhost:3000` -- Superset: `http://localhost:8088` - ---- - -## 1) Сценарий на 5 минут (тайминг + реплики) - -### 0:00–0:30 — Контекст - -Что открыть: -- README/схему архитектуры или короткий слайд. - -Что сказать: -- «Это мини-DWH кликстрима: Kafka + ClickHouse + Airflow + Superset + Prometheus/Grafana.» -- «Поток: JSONL -> Kafka -> STG -> ODS -> DDS -> DM-витрины.» -- «Ключевая цель: быстрый повторяемый прогон и устойчивость к грязным данным.» - -### 0:30–1:20 — Оркестрация в Airflow - -Что открыть: -- Airflow UI, DAG-и `ddl_init`, `kafka_load`, `etl_pipeline`. - -Что сказать: -- «`ddl_init` создаёт DDL, `kafka_load` грузит данные в Kafka, `etl_pipeline` считает слои.» -- «Запуск ручной, параметры прозрачные: `limit`, `reset_topics`, `full_refresh`.» - -### 1:20–2:10 — Ingest через Kafka - -Что открыть: -- Kafka UI (топики/сообщения), затем ClickHouse STG. - -Что сказать: -- «Одна строка входа = одно сообщение Kafka.» -- «В STG храним сырой JSON без потери данных, типизация делается позже в ODS.» - -### 2:10–3:20 — Проверка результата в ClickHouse - -Что открыть: -- ClickHouse Play и выполнить запросы ниже. - -Что сказать: -- «Показываю факт прохождения по слоям и готовые витрины для аналитики.» - -```sql -SELECT count() AS rows FROM ods.browser_event; -SELECT count() AS rows FROM dds.event; -SELECT count() AS rows FROM dds.click; -SELECT * FROM dm.v_daily_traffic ORDER BY event_date DESC LIMIT 10; -SELECT * FROM dm.v_utm_effectiveness ORDER BY clicks DESC LIMIT 10; -``` - -### 3:20–4:10 — Качество данных и устойчивость - -Что открыть: -- `dm.dq_summary` и/или `ods.*_errors`. - -Что сказать: -- «Грязные записи не валят пайплайн: ошибки фиксируются в ODS и отражаются в DQ summary.» -- «Это важнее “идеально чистого” датасета, потому что поведение ближе к прод-среде.» - -```sql -SELECT * FROM dm.dq_summary ORDER BY layer, table_name, check_name LIMIT 20; -``` - -### 4:10–5:00 — Мониторинг и BI - -Что открыть: -- Grafana (overview-дашборд) и Superset (одна витрина/чарт). - -Что сказать: -- «Есть observability: метрики по ClickHouse/Kafka/Airflow и алерты.» -- «Есть BI-слой: витрины готовы для первичного анализа без ручных выгрузок.» - ---- - -## 2) План Б, если UI тормозит - -Показать то же самое через CLI: - -```bash -docker compose ps -docker compose exec -T clickhouse clickhouse-client --user=default --password=123456 --query "SELECT count() FROM dds.event" -docker compose exec -T clickhouse clickhouse-client --user=default --password=123456 --query "SELECT * FROM dm.dq_summary LIMIT 10" -curl -s http://localhost:9090/api/v1/targets | grep -o '"health":"[^"]*"' -``` - -Короткая реплика: -- «Даже без UI видно, что pipeline отработал, витрины заполнены, мониторинг жив.» - ---- - -## 3) Финальная фраза (15 секунд) - -- «Проект показывает полный цикл DE-задачи: инфраструктура, ingestion, слои данных, DQ, витрины и мониторинг.» -- «Если нужно, могу углубиться в любой блок: DAG, SQL-трансформации, модель данных или алерты.» diff --git a/docs/DEMO_SCRIPT_10_15MIN.md b/docs/DEMO_SCRIPT_10_15MIN.md deleted file mode 100644 index 16a82c3..0000000 --- a/docs/DEMO_SCRIPT_10_15MIN.md +++ /dev/null @@ -1,182 +0,0 @@ -# Сценарий демо на 10-15 минут (код + архитектура) - -Цель: дать студенту готовый сценарий, который показывает не только запуск стенда, но и инженерные решения в коде. - -Формат: запись экрана + голос. -Ориентир по времени: 12 минут (допуск 10-15). - ---- - -## 1) Подготовка перед записью (за 10-20 минут) - -```bash -make up -docker compose ps -docker compose exec -T airflow-webserver airflow dags trigger ddl_init -docker compose exec -T airflow-webserver airflow dags trigger kafka_load --conf '{"limit": 50, "reset_topics": true}' -docker compose exec -T airflow-webserver airflow dags trigger etl_pipeline --conf '{"full_refresh": true}' -``` - -Проверить, что открываются: -- Kafka UI: `http://localhost:8082` -- Grafana: `http://localhost:3000/d/clickhouse-overview/clickhouse-overview` -- Airflow: `http://localhost:8080/dags/ddl_init/grid?tab=details` -- Superset (если используете): `http://localhost:8088/login/?next=/` -- ClickHouse Play: `http://localhost:9123/play` - -Подготовить вкладки заранее: -- `Makefile` -- `docker-compose.yml` -- `docs/ARCHITECTURE.md` -- `airflow/dags/ddl_init_dag.py` -- `airflow/dags/kafka_load_dag.py` -- `airflow/dags/etl_pipeline_dag.py` -- `sql/ddl/stg/10_stg.sql` -- `sql/ods/20_stg_to_ods.sql` -- `sql/dds/30_ods_to_dds.sql` -- `sql/dm/40_dds_to_dm.sql` - -Опционально подготовить DBeaver (если хотите показывать не через Play): -- Host: `localhost` -- Port: `9123` (HTTP) или `8002` (native) -- User: `default` -- Password: `123456` - ---- - -## 2) Поминутный план выступления - -### 0:00-1:30 Инфраструктура и цель проекта - -Что показывать: -- Терминал с `docker compose ps` -- `Makefile` -- `docker-compose.yml` - -Что говорить: -- «Это учебный mini DWH для кликстрима: Kafka, ClickHouse, Airflow, Superset, Prometheus, Grafana.» -- «Инфраструктура поднимается одной командой `make up`; внутри это `docker compose up -d`.» -- «В `Makefile` также есть команды для остановки, очистки, перезагрузки мониторинга и recovery.» -- «Сервисная цель проекта: быстро и повторяемо показать end-to-end поток данных до витрин.» - -Что подчеркнуть в коде: -- В `Makefile` показать цели `up/down/clean/reload-monitoring/recover-monitoring`. -- В `docker-compose.yml` бегло показать ключевые сервисы и порты. - -### 1:30-3:30 Архитектура и логика выбора - -Что показывать: -- `docs/ARCHITECTURE.md` (диаграммы потока, слои STG/ODS/DDS/DM). - -Что говорить: -- «Управление сделано через 3 DAG: `ddl_init`, `kafka_load`, `etl_pipeline`.» -- «STG нужен для сырых событий как есть, чтобы сохранять воспроизводимость.» -- «ODS типизирует и валидирует данные, включая фиксацию ошибок парсинга.» -- «DDS собирает бизнес-сущности `event` и `click` для аналитики.» -- «DM отдает витрины и агрегаты для BI и интервью-демо.» - -Объяснение решений: -- «Разделение на слои уменьшает связность и ускоряет диагностику проблем.» -- «Грязные данные не останавливают пайплайн: ошибки уходят в `ods.*_errors` и DQ-слой.» - -### 3:30-6:30 Показ кода DAG-ов - -Что показывать: -- `airflow/dags/ddl_init_dag.py` -- `airflow/dags/kafka_load_dag.py` -- `airflow/dags/etl_pipeline_dag.py` - -Что говорить: -- «В `ddl_init` код разворачивает DDL в ClickHouse и подготавливает структуру слоев.» -- «В `kafka_load` есть управляемые параметры `limit` и `reset_topics` для быстрого smoke-прогона.» -- «В `etl_pipeline` выполняются шаги STG->ODS->DDS->DM с конфигурацией `full_refresh`; итоговый DM-блок здесь — загрузка `dm.dq_summary`.» -- «Логика запуска ручная: это удобно для демонстрации на собеседовании и для отладки.» - -Что обязательно назвать: -- «Почему `limit=50` в демо: скорость и повторяемость важнее полноты.» -- «Почему DAG-и разделены: проще локализовать сбой и перезапустить только нужный этап.» - -### 6:30-8:30 Показ SQL и модели данных - -Что показывать: -- `sql/ddl/stg/10_stg.sql` -- `sql/ods/20_stg_to_ods.sql` -- `sql/dds/30_ods_to_dds.sql` -- `sql/dm/40_dds_to_dm.sql` - -Что говорить: -- «В STG используется связка Kafka Engine + Materialized View + MergeTree таблицы.» -- «ODS делает типизацию, нормализацию и отправку проблемных строк в таблицы ошибок.» -- «DDS собирает сущности по ключам (`event_id`, `click_id`), чтобы упростить аналитику.» -- «Витрины DM строятся поверх DDS и готовы для BI.» - -Короткий акцент на DQ: -- «Вместо падения на невалидном JSON сохраняем ошибку и продолжаем обработку потока.» - -### 8:30-10:30 Прогон в Airflow + проверка результата - -Что показывать: -- Airflow UI: последний `Success` у `ddl_init`, `kafka_load`, `etl_pipeline` -- ClickHouse Play или DBeaver - -Что выполнять: - -```sql -SELECT count() AS rows FROM stg.browser_raw; -SELECT count() AS rows FROM ods.browser_event; -SELECT count() AS rows FROM dds.event; -SELECT * FROM dm.v_daily_traffic ORDER BY event_date DESC LIMIT 10; -SELECT * FROM dm.dq_summary ORDER BY layer, table_name, check_name LIMIT 20; -``` - -Что говорить: -- «На экране видно прохождение данных по слоям и непустые витрины.» -- «DQ summary подтверждает контроль качества и обработку проблемных записей.» - -### 10:30-12:00 Мониторинг и финал - -Что показывать: -- Grafana: ClickHouse/Kafka/Airflow dashboards -- Prometheus targets (опционально) -- Superset dashboard (если подготовлен) - -Что говорить: -- «Мониторинг показывает здоровье стенда и ключевые технические метрики.» -- «На BI-слое уже можно отвечать на базовые бизнес-вопросы по трафику и UTM.» -- «Итог: решение покрывает инфраструктуру, ingestion, трансформации, DQ, витрины и observability.» - ---- - -## 3) План Б, если что-то сломалось на записи - -Если не открывается UI: - -```bash -docker compose ps -docker compose logs -f --tail=100 airflow-webserver -docker compose exec -T clickhouse clickhouse-client --user=default --password=123456 --query "SELECT count() FROM dds.event" -curl -s http://localhost:9090/api/v1/targets | grep -o '"health":"[^"]*"' -``` - -Если Grafana пустая: - -```bash -make reload-monitoring -``` - -Если мониторинг завис: - -```bash -make recover-monitoring -``` - -Короткая реплика: -- «Даже при проблемах UI я показываю проверку через CLI и SQL, чтобы подтвердить работоспособность пайплайна.» - ---- - -## 4) Готовый текст финала (20-30 секунд) - -«Я реализовал end-to-end mini DWH для кликстрима: от инфраструктуры и ingestion до витрин и мониторинга. -Архитектура послойная STG-ODS-DDS-DM, orchestration через Airflow DAG-и, а невалидные данные фиксируются без падения пайплайна. -Если нужно, могу детально разобрать любой уровень: DAG-код, SQL-трансформации, DQ-проверки или наблюдаемость системы.» diff --git a/docs/course/PRD.md b/docs/course/PRD.md index b3769f0..8083b8b 100644 --- a/docs/course/PRD.md +++ b/docs/course/PRD.md @@ -9,6 +9,13 @@ > Поправка 2026-06-03 (терминология): режим сопровождения — еженедельный **созвон**, а не > «сессия»; менти проходит материал сам и ничего «не приносит», а на созвоне ментор > разбирает затыки и проверяет глубину понимания. Затронуты §1, §3, §5. +> Поправка 2026-07-04 (целеполагание): §1 расширен — зафиксировано место стенда в +> экосистеме менторской программы (теория и лабы по ClickHouse живут в других местах, +> здесь — интеграции «как в жизни») и иерархия целей вплоть до генератора. Демо-материалы +> (шпаргалки 5 и 10–15 минут) устарели и удалены: демо выросло в отдельный проект и целью +> стенда больше не является. Схема потока в §1 обновлена под генератор (источник данных +> сменился, см. ADR-0006). В §7 закрыта развилка про урок о генераторе и добавлена +> развилка про кластерную конфигурацию. > Назначение документа: зафиксировать для будущих сессий, что это за курс, зачем > он, что входит в скоуп работ, а что нет. Это договорная **рамка**, а не план > реализации и не стандарт уроков (см. раздел «Связанные документы»). @@ -23,8 +30,8 @@ Репозиторий — рабочий сквозной стенд кликстрим-DWH: ``` -data/*.jsonl → Kafka → ClickHouse (Kafka engine + MV → STG) → Airflow ETL (STG→ODS→DDS→DM) → Superset - ↘ Prometheus / Grafana (мониторинг) +generator (backfill/live) → Kafka → ClickHouse (Kafka engine + MV → STG) → Airflow ETL (STG→ODS→DDS→DM) → Superset + ↘ Prometheus / Grafana (мониторинг) ``` Стенд близок к продакшену и показывает несколько паттернов инженерии данных на @@ -32,6 +39,33 @@ data/*.jsonl → Kafka → ClickHouse (Kafka engine + MV → STG) → Airflow ET программу обучения — это **продвинутый курс «со звёздочкой»** для менти, уже прошедших базу (SQL, моделирование, Python, Git, Docker, Airflow). +### Место стенда в менторской программе (2026-07-04) + +Трек ClickHouse для продвинутых менти состоит из трёх частей, и у каждой своя роль: + +- **Теория** — внешние курсы (бесплатный курс Яндекса или запись курса Отус). + Здесь теорию не пересказываем. +- **Лабы по самому ClickHouse** — отдельный стенд + [clickhouse-learning-cluster](https://github.com/dementev-dev/clickhouse-learning-cluster): + полноценный кластер, но без внешних интеграций. +- **Этот стенд** — то, чего нет в первых двух: ClickHouse в окружении «как в жизни». + Интеграции (Kafka, Airflow), мониторинг и BI поверх. Ниша стенда — не сам + ClickHouse, а инженерия данных вокруг него. + +Иерархия целей внутри репозитория: + +1. **Курс — главная цель.** Всё остальное — средства. +2. **Стенд — носитель курса.** Должен подниматься одной командой, давать + правдоподобные данные (пирамида «пользователи < визиты < события», суточная + волна, возвраты) и быстро воспроизводиться. +3. **Генератор — скрытая инфраструктура стенда.** Его задача — живые данные: + стартовая история плюс живое продолжение. Учебным предметом не является + (решение — §7); пользовательская граница — «как пользоваться», не «как устроен». + +Демо-употребление стенда (шпаргалки на 5 и 10–15 минут) **устарело**: демо выросло +в отдельный проект и целью этого репозитория больше не является (2026-07-04, +материалы удалены). + Цель курса — превратить стенд в **самостоятельный учебный материал**, по которому продвинутый менти проходит ключевые паттерны сам, а ментор подключается на обычном еженедельном созвоне (что получилось / что нет / вопросы / план на неделю). Долгий @@ -139,17 +173,28 @@ Kafka → ClickHouse → BI). синхронизирован с реальным дашбордом; остаётся опциональным (обязательные уроки не блокирует). +Закрыто позже: + +- ~~Генератор как инфраструктура против отдельного урока (открыто, 2026-06-14).~~ + **Решено (2026-07-04): отдельного урока про генератор не будет — генератор + остаётся скрытой инфраструктурой.** Причина: устройство генератора (марковская + модель, нетривиальный Python) — это разработка бэкенда и математика, а не + инженерия данных; такой урок не попадает в цели курса, и менти его не ожидает. + Существующие уроки адаптируем без ввода марковских цепей и сложного Python в + путь менти (задача — `.scratch/generator-model-time-startup-history/issues/08-migrate-course-from-archive-seed.md`). + Удобство стенда (одна команда + короткий runbook) остаётся отдельной задачей + (`.scratch/generator-model-time-startup-history/issues/07-startup-history-portable-artifact-and-usage-docs.md`) + и делает адаптацию уроков проще, но решение от неё больше не зависит. + Остаётся на будущее: - Переиспользование: после **первого реального прогона менти** — ретроспектива и обобщение материала под других менти. Это валидация уже собранного курса, а не часть его подготовки. -- Генератор как инфраструктура против отдельного урока (открыто, 2026-06-14). - Устройство генератора вышло сложным (марковская модель, нетривиальный Python), а - цель менти — быстро потренироваться в ClickHouse/Kafka. Вопрос: делать ли - отдельный урок про генератор (возможный «урок 7») или оставить генератор скрытой - инфраструктурой и **адаптировать существующие уроки**, не вводя марковские цепи и - сложный Python в путь менти. Решение зависит от удобства стенда: если он - поднимается одной командой и есть короткий runbook (см. бэклог фичи генератора, - `.scratch/generator-model-time-startup-history/issues/08-startup-history-portable-artifact-and-usage-docs.md`), - отдельный урок, скорее всего, не нужен. +- Кластерная конфигурация ClickHouse (открыто, 2026-07-04). Сейчас стенд — + одноузловой ClickHouse; кластер живёт в соседнем + [clickhouse-learning-cluster](https://github.com/dementev-dev/clickhouse-learning-cluster). + Развилка: оставить разделение «здесь интеграции, там кластер» или доработать этот + стенд до кластера — «всё в одном» удобнее и ближе к промышленной системе, но + ощутимо утяжеляет стенд (ресурсы, конфигурация, сложность уроков) и размывает + нишу learning-cluster. Решение не принято.