From 3f76d66ed13e5fbf8674e39b534e4ed889c9316c Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Sat, 7 Mar 2026 00:38:26 +0300 Subject: [PATCH] =?UTF-8?q?docs(readme):=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20student-facing=20=D0=B8=20=D0=B2?= =?UTF-8?q?=D0=BD=D1=83=D1=82=D1=80=D0=B5=D0=BD=D0=BD=D0=B8=D0=B5=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - нужно убрать смешение маршрута студента с внутренними документами сопровождения репозитория. - Что: - переработан README.md как верхнеуровневый вход в репозиторий без ссылок на внутренние maintainer-документы. - добавлен docs/stack_reference.md для технического reference стенда и уточнены его роли относительно START_HERE.md. - синхронизированы AGENTS.md и docs/maintainer_guide.md под новую границу между onboarding и внутренней документацией. - Проверка: - сверены README.md, START_HERE.md, docs/stack_reference.md, AGENTS.md и docs/maintainer_guide.md на согласованность маршрута и аудиторий. --- AGENTS.md | 5 +- README.md | 397 +++++---------------------------------- docs/maintainer_guide.md | 9 +- docs/stack_reference.md | 172 +++++++++++++++++ 4 files changed, 233 insertions(+), 350 deletions(-) create mode 100644 docs/stack_reference.md diff --git a/AGENTS.md b/AGENTS.md index 8a37f41..74065f2 100755 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,8 +6,9 @@ ## Канонические документы -- `README.md` — верхнеуровневое описание стенда, архитектуры и сервисов. +- `README.md` — верхнеуровневое описание репозитория, архитектуры и точек входа. - `START_HERE.md` — первый маршрут для студента до запуска ноутбуков. +- `docs/stack_reference.md` — технический reference по сервисам, портам, доступу и smoke-тестам. - `docs/course_prd.md` — рамки курса, learning outcomes, scope и out of scope. - `docs/course_program.md` — модульная структура курса и состав учебных материалов. - `docs/maintainer_guide.md` — карта репозитория и правила синхронизации изменений. @@ -26,7 +27,7 @@ ## Правила изменений - Сначала меняй канонический документ для соответствующего слоя, потом синхронизируй связанные ссылки и упоминания. -- Если меняются сервисы, порты, имена контейнеров, образы или команды запуска, обновляй как минимум `README.md`, `START_HERE.md` и затронутые примеры. +- Если меняются сервисы, порты, имена контейнеров, образы или команды запуска, обновляй как минимум `README.md`, `START_HERE.md`, `docs/stack_reference.md` и затронутые примеры. - Если меняются scope курса, learning outcomes или модульная структура, обновляй `docs/course_prd.md` и `docs/course_program.md`, а не только `plans/`. - Поддерживай согласованный маршрут `README -> START_HERE -> docs/course_program.md -> notebooks/src`. - Не дублируй крупные фрагменты между документами, если можно сослаться на канонический файл. diff --git a/README.md b/README.md index 5190000..a80f79e 100755 --- a/README.md +++ b/README.md @@ -1,17 +1,12 @@ -# Учебный Lakehouse-стенд (Trino + Spark + Iceberg + MinIO) +# Lakehouse без магии: локальный стенд и учебные материалы -Учебный стенд для демонстрации **Lakehouse-архитектуры** на одном ноутбуке: +Этот репозиторий объединяет: -- объектное хранилище S3-класса (MinIO), -- движок запросов Trino, -- Spark для batch/ETL и интерактивных экспериментов, -- формат таблиц Iceberg, -- JDBC-каталог (PostgreSQL) для метаданных Iceberg в Trino, -- конфиг Spark, заточенный под работу с Iceberg + S3. +- локальный Lakehouse-стенд на `Spark + Trino + Iceberg + MinIO + PostgreSQL`; +- учебный курс `Lakehouse без магии`, который использует этот стенд как практическую среду; +- стартовые ноутбуки и demo-скрипты для первых экспериментов. -Стенд ориентирован на обучение менти и быструю демонстрацию концепции Lakehouse: разделение **storage / compute / catalog** без лишней обвязки (Hive Metastore, полноценный Hadoop-кластер и т.п.). - ---- +Репозиторий рассчитан не на «универсальную платформу для всего», а на понятную локальную песочницу, где можно руками пройти путь от запуска стенда до чтения одной и той же Iceberg-таблицы из `Spark` и `Trino`. ## Архитектура @@ -36,363 +31,73 @@ graph LR T <--> P ``` -**Основные идеи:** +Коротко по ролям: -* **Данные** (Parquet-файлы + служебные каталоги Iceberg) лежат в бакете MinIO (`s3a://lakehouse/warehouse/...`). -* **Метаданные** Iceberg хранятся в PostgreSQL (JDBC-каталог `lakehouse`). -* **Spark и Trino** используют один и тот же JDBC-каталог: таблицы, созданные в Spark, доступны в Trino, и наоборот. +- `MinIO` хранит данные и служебные файлы Iceberg. +- `PostgreSQL` хранит метаданные JDBC-каталога `lakehouse`. +- `Spark` и `Trino` работают как два compute-движка поверх одного storage и одного catalog. +- `Jupyter` служит точкой входа в практическую часть курса. ---- +## С чего начать -## Быстрый старт +Если ты заходишь в репозиторий впервые, используй такой маршрут: -Подробный маршрут старта вынесен в [START_HERE.md](./START_HERE.md). Если нужен только краткий запуск, достаточно: +1. Открой [START_HERE.md](./START_HERE.md) для первого запуска стенда и базовой диагностики. +2. После старта стенда выполни `notebooks/01_environment_and_smoke_test.ipynb`. +3. Для структуры курса смотри [docs/course_program.md](./docs/course_program.md). -1. Установить Docker и Docker Compose (см. раздел «Требования» ниже). -2. В корне репозитория выполнить: - - ```bash - docker compose build - docker compose up -d - ``` - -3. Открыть основные интерфейсы: - - - Spark Master UI: `http://localhost:8080` - - Trino Web UI: `http://localhost:8090` - - MinIO Console: `http://localhost:9001` - - JupyterLab (если включён): `http://localhost:8888` - -4. Для входа в курс и Модуль 1 открыть `START_HERE.md`. -5. Актуальная структура курса описана в `docs/course_program.md`. - ---- - -## Состав репозитория - -* `docker-compose.yml` — описание всех сервисов стенда: - - * Spark master / worker(ы) на базе кастомного образа `spark-iceberg`, - * Trino, - * MinIO (S3-совместимое хранилище), - * PostgreSQL под Iceberg JDBC-каталог, - * (опционально) Jupyter / notebook для PySpark. -* `spark/Dockerfile` — сборка кастомного образа **Spark** с зависимостями: - - * `hadoop-aws`, `aws-java-sdk`, - * библиотека Iceberg нужной версии, - * `pyspark`, `pyarrow` и базовый набор инструментов. -* `jupyter/Dockerfile` — образ JupyterLab на базе Spark-образа. -* `START_HERE.md` — канонический маршрут входа в курс до первого ноутбука. -* `plans/` — внутренние living docs с планами работ по модулям курса. -* `spark/spark-defaults.conf` — конфигурация Spark для работы с: - - * Iceberg-каталогом `lakehouse` (тип `jdbc`, метаданные в Postgres), - * MinIO через `s3a://`, - * расширениями `IcebergSparkSessionExtensions`. -* `src/` — учебные примеры для Spark и Trino: - - * `src/spark/cluster_smoke.py` — проверка, что кластер жив (Spark master/worker). - * `src/spark/iceberg_smoke.py` — Spark создаёт Iceberg-таблицу и читает её. - * `src/spark/iceberg_demo.sql` — пример создания Iceberg-таблицы через Spark SQL. - * `src/trino/iceberg_smoke.sql` — Trino читает таблицу, созданную в Spark. -* `trino/catalog/lakehouse.properties` — конфиг каталога Trino `lakehouse`: - - * коннектор `iceberg`, - * `jdbc`-каталог (PostgreSQL), - * доступ к MinIO как к S3-хранилищу. - ---- - -## Требования - -- Docker и Docker Compose. -- Порты по умолчанию должны быть свободны (см. таблицу «Сервисы и порты» ниже). - -### Сервисы и порты - -| Сервис | Контейнер | Порт (host → container) | Назначение / UI | -|------------------------|-------------------|-------------------------|-------------------------------------| -| Trino | `trino` | `8090 → 8080` | Web UI Trino | -| MinIO API | `minio` | `9000 → 9000` | S3 endpoint | -| MinIO Console | `minio` | `9001 → 9001` | Веб-консоль MinIO | -| PostgreSQL (каталог) | `postgres-iceberg`| `5432 → 5432` | Доступ для psql/DBeaver и т.п. | -| Spark master UI | `spark-master` | `8080 → 8080` | Web UI мастера Spark | -| Spark worker-1 UI | `spark-worker-1` | `8081 → 8081` | Web UI первого воркера | -| Spark worker-2 UI | `spark-worker-2` | `8082 → 8081` | Web UI второго воркера (host 8082) | -| JupyterLab | `jupyter` | `8888 → 8888` | JupyterLab с PySpark | - ---- - -## Сборка и запуск - -Все команды в этом разделе выполняются из корня репозитория. - -### 1. Собрать образы +Если нужен только краткий запуск, из корня репозитория достаточно: ```bash docker compose build -``` - -Будут собраны кастомные образы Spark/Jupyter с зависимостями Iceberg, S3A, JDBC-драйвером Postgres и Python-библиотеками. - -### 2. Поднять стенд - -```bash docker compose up -d -``` - -Что происходит при старте: - -* MinIO поднимается с root-пользователем/паролем (по умолчанию смотри в `docker-compose.yml`, обычно `minioadmin/minioadmin`), init-контейнер создаёт бакет `lakehouse`. -* PostgreSQL под каталог Iceberg создаёт БД и пользователя (значения — в `docker-compose.yml` / `.env`). -* Trino стартует с каталогом `lakehouse`, описанным в `lakehouse.properties`. -* Spark master/worker получают конфиг из `spark-defaults.conf` (общий JDBC-каталог Iceberg + MinIO). - -Проверить статус: - -```bash docker compose ps ``` -### 3. Остановить стенд и очистить данные +Основные UI после старта: -Чтобы остановить все сервисы и удалить данные в MinIO/PostgreSQL (Docker volumes), можно выполнить: +- Spark Master UI: `http://localhost:8080` +- Trino UI: `http://localhost:8090` +- MinIO Console: `http://localhost:9001` +- JupyterLab: `http://localhost:8888` -```bash -docker compose down -v -``` +Полный onboarding, диагностика и reset-сценарии находятся в `START_HERE.md`. ---- +## Как устроен репозиторий -## Доступ к сервисам +| Где | Что лежит | +| --- | --- | +| `docker-compose.yml` | состав сервисов стенда, порты, сети, init-контейнеры | +| `spark/` | Dockerfile и конфиг Spark для Iceberg + MinIO | +| `trino/` | каталог `lakehouse` и настройки Trino | +| `jupyter/` | образ JupyterLab на базе Spark-образа | +| `notebooks/` | практические ноутбуки курса | +| `src/` | smoke-скрипты, SQL-демо и helper-логика | +| `docs/` | PRD, программа курса, reference-документы | +| `plans/` | внутренние living docs по развитию материалов | -### Trino +## Основные документы для прохождения -Web UI (координатор): +- [START_HERE.md](./START_HERE.md) — первый маршрут для студента. +- [docs/course_program.md](./docs/course_program.md) — модульная структура и состав учебных материалов. +- [docs/stack_reference.md](./docs/stack_reference.md) — технический reference по сервисам, портам, конфигам и smoke-тестам. -```text -http://localhost:8090 -``` +## Что уже можно делать в стенде -(точный порт см. в `docker-compose.yml`). +- поднять локальный кластер `Spark` с двумя worker-ами; +- создать Iceberg-таблицу из `Spark`; +- прочитать ту же таблицу из `Trino`; +- пройти базовый smoke test через ноутбук или demo-скрипты; +- использовать стенд как основу для следующих модулей курса. -Подключение **из контейнера trino**: +## Куда смотреть за техническими деталями -```bash -docker exec -it trino trino \ - --server http://localhost:8080 \ - --catalog lakehouse -``` - -Проверка: - -```sql -SHOW CATALOGS; -SHOW SCHEMAS FROM lakehouse; -``` - -### MinIO - -* Консоль: `http://localhost:9001` -* S3 endpoint: `http://localhost:9000` - -Учётные данные — `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` из `docker-compose.yml` или `.env`. - -Создай в MinIO бакет `lakehouse` (если его нет) — данные Iceberg будут храниться именно там. - -### PostgreSQL (каталог Iceberg для Trino) - -Подключение (пример): - -```bash -psql -h localhost -p 5432 -U iceberg -d iceberg -``` - -(имя пользователя, БД и порт уточняются в `docker-compose.yml`). - -Служебные таблицы Iceberg JDBC-каталога (`iceberg_tables`, `iceberg_namespace_properties`) создаёт однократный контейнер `iceberg-catalog-init`. Если база уже запускалась без них, можно переинициализировать вручную: - -```bash -docker compose run --rm iceberg-catalog-init -``` - -### Jupyter / notebooks - -Веб-интерфейс: `http://localhost:8888` (по умолчанию без токена). - -* В контейнере монтируется `./notebooks` в `/opt/work`. -* `./src` доступен read-only в `/opt/src`, переменная `PYTHONPATH=/opt/src` уже установлена — можно импортировать функции из скриптов прямо в ноутбуках. -* Первый канонический ноутбук курса: `notebooks/01_environment_and_smoke_test.ipynb`. - ---- - -## Конфигурация Trino (каталог `lakehouse`) - -Файл `lakehouse.properties` монтируется в `/etc/trino/catalog/lakehouse.properties`. - -Ключевые параметры: - -```properties -connector.name=iceberg - -# Каталог Iceberg типа JDBC (метаданные в PostgreSQL) -iceberg.catalog.type=jdbc -iceberg.jdbc-catalog.catalog-name=lakehouse -iceberg.jdbc-catalog.driver-class=org.postgresql.Driver -iceberg.jdbc-catalog.connection-url=jdbc:postgresql://postgres-iceberg:5432/iceberg -iceberg.jdbc-catalog.connection-user=iceberg -iceberg.jdbc-catalog.connection-password=iceberg -iceberg.jdbc-catalog.schema-version=V1 - -# Хранилище файлов Iceberg – S3 (MinIO) через hadoop-клиент -iceberg.file-system.type=hadoop -fs.native-s3.enabled=true - -s3.endpoint=http://minio:9000 -s3.region=us-east-1 -s3.path-style-access=true -s3.aws-access-key=minioadmin -s3.aws-secret-key=minioadmin -``` - -**Что это даёт:** - -* Trino хранит *метаданные* Iceberg в PostgreSQL (таблицы каталога, снапшоты, манифесты и т.п.). -* *Файлы данных* лежат в MinIO, в бакете `lakehouse`, к которому Trino ходит по `s3://`/`s3a://` через S3-клиент. - -Пример создания схемы и таблицы из Trino: - -```sql --- Схема в каталоге lakehouse (метаданные в PostgreSQL) -CREATE SCHEMA lakehouse.default; - --- Таблица Iceberg с данными в s3://lakehouse/default/test_table/ -CREATE TABLE lakehouse.default.test_table ( - id bigint, - name varchar -); -``` - ---- - -## Конфигурация Spark (spark-defaults.conf) - -`spark-defaults.conf` монтируется в `/opt/spark/conf/spark-defaults.conf` в контейнеры Spark. - -Ключевые моменты: - -```properties -# Iceberg Spark extensions -spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions - -# Каталог Iceberg для Spark (JDBC, метаданные в Postgres) -spark.sql.catalog.lakehouse=org.apache.iceberg.spark.SparkCatalog -spark.sql.catalog.lakehouse.catalog-impl=org.apache.iceberg.jdbc.JdbcCatalog -spark.sql.catalog.lakehouse.uri=jdbc:postgresql://postgres-iceberg:5432/iceberg -spark.sql.catalog.lakehouse.jdbc.user=iceberg -spark.sql.catalog.lakehouse.jdbc.password=iceberg -spark.sql.catalog.lakehouse.jdbc.driver=org.postgresql.Driver -spark.sql.catalog.lakehouse.warehouse=s3a://lakehouse/warehouse -spark.sql.catalog.lakehouse.default-namespace=default - -# S3/MinIO через s3a -spark.hadoop.fs.s3a.endpoint=http://minio:9000 -spark.hadoop.fs.s3a.access.key=minioadmin -spark.hadoop.fs.s3a.secret.key=minioadmin -spark.hadoop.fs.s3a.path.style.access=true -spark.hadoop.fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem -spark.hadoop.fs.s3a.connection.ssl.enabled=false -``` - -**Важно:** Spark и Trino используют единый JDBC-каталог `lakehouse`: метаданные лежат в Postgres, данные — в MinIO. Таблица, созданная в Spark, видна в Trino без дополнительной настройки. - -Пример создания таблицы из Spark: - -```python -from pyspark.sql import SparkSession - -spark = (SparkSession.builder - .appName("lakehouse-demo") - .getOrCreate()) - -# Каталог lakehouse указан явно -spark.sql(""" - CREATE TABLE lakehouse.default.spark_table ( - id BIGINT, - name STRING - ) - USING iceberg -""") - -spark.sql("INSERT INTO lakehouse.default.spark_table VALUES (1, 'Alice'), (2, 'Bob')") -``` - -Файлы окажутся в `s3a://lakehouse/warehouse/default/spark_table/`. - ---- - -## Типовой учебный сценарий - -1. **Поднять стенд** (`docker compose build`, затем `docker compose up -d`). -2. **Создать бакет `lakehouse`** в MinIO Console (если ещё нет). -3. **Создать таблицу из Spark**, записать туда данные, показать дерево файлов Iceberg в MinIO (data/manifest/metadata). -4. **Прочитать ту же таблицу из Trino** (проверка общего каталога). -5. **Создать таблицу из Trino** и прочитать её из Spark. -6. Обсудить архитектуру: Postgres хранит метаданные Iceberg, MinIO — данные, Spark/Trino — compute. - ---- - -## Smoke-тесты Spark → Trino - -Быстрая проверка, что таблица, созданная в Spark, читается в Trino через общий JDBC-каталог. - -1. Убедиться, что стенд запущен: `docker compose up -d`. -2. Скопировать скрипты внутрь контейнеров: - - ```bash - docker compose cp src/spark/iceberg_smoke.py spark-master:/tmp/ - docker compose cp src/trino/iceberg_smoke.sql trino:/tmp/ - ``` - -3. Выполнить smoke из Spark: - - ```bash - docker compose exec spark-master /opt/spark/bin/spark-submit /tmp/iceberg_smoke.py - ``` - - Скрипт создаст `lakehouse.default.spark_trino_smoke`, вставит строку `1, from_spark` и прочитает её. - -4. Прочитать ту же таблицу из Trino: - - ```bash - docker compose exec trino trino --file /tmp/iceberg_smoke.sql - ``` - - В выводе должны быть строки `spark_trino_smoke` в списке таблиц и `1, from_spark` в результате выборки. - -5. Очистка (опционально): - - ```bash - docker compose exec spark-master /opt/spark/bin/spark-sql -e "DROP TABLE IF EXISTS lakehouse.default.spark_trino_smoke" - ``` - ---- - -## Дальнейшее развитие - -Планируемые/возможные расширения: - -* Подключить **Airflow** и запускать Spark-job’ы поверх этого же Lakehouse. -* Вынести настройки (`MINIO_ROOT_USER`, `ICEBERG_*`, `POSTGRES_*`) в `.env` с шаблоном для студентов. -* Добавить отдельные каталоги Trino (например, `hive`, `tpch`) для демонстрации федеративных запросов. -* Добавить пример интеграции с BI-инструментом (DBeaver/Metabase/Superset) поверх Trino. - -Актуальная структура курса описана в `docs/course_program.md`. Старый `HOWTO` сохранён как архивный материал в `docs/archive/legacy_howto.md`. - ---- +- [docs/stack_reference.md](./docs/stack_reference.md) — сервисы, порты, доступ, reset, smoke tests; +- [spark/spark-defaults.conf](./spark/spark-defaults.conf) — конфигурация Spark-каталога `lakehouse`; +- [trino/catalog/lakehouse.properties](./trino/catalog/lakehouse.properties) — конфигурация каталога Trino; +- [docker-compose.yml](./docker-compose.yml) — фактический состав стенда. ## Лицензия -Материалы этого репозитория лицензированы на условиях Creative Commons Attribution 4.0 International (CC BY 4.0). -См. файл `LICENSE` или . +Материалы этого репозитория лицензированы на условиях Creative Commons Attribution 4.0 International (`CC BY 4.0`). +См. [LICENSE](./LICENSE). diff --git a/docs/maintainer_guide.md b/docs/maintainer_guide.md index 52b6f79..d85920a 100644 --- a/docs/maintainer_guide.md +++ b/docs/maintainer_guide.md @@ -2,6 +2,8 @@ Этот документ нужен, чтобы не раздувать `AGENTS.md` и не дублировать изменчивый контекст проекта в нескольких местах. +Это внутренний документ сопровождения репозитория. Для прохождения курса и первого запуска стенда он обычно не нужен. + ## Что это за репозиторий сейчас Репозиторий состоит из двух тесно связанных слоёв: @@ -16,7 +18,8 @@ | Зона | Где лежит | Назначение | | --- | --- | --- | | Runtime / stand | `docker-compose.yml`, `spark/`, `trino/`, `jupyter/` | Топология сервисов, образы, конфиги, порты | -| Onboarding | `README.md`, `START_HERE.md` | Вход в стенд и первый пользовательский маршрут | +| Onboarding | `README.md`, `START_HERE.md` | Вход в репозиторий и первый пользовательский маршрут | +| Runtime reference | `docs/stack_reference.md` | Технические детали стенда: порты, доступ, команды, smoke-тесты | | Course definition | `docs/course_prd.md`, `docs/course_program.md` | Границы курса, learning outcomes, структура модулей | | Practice materials | `notebooks/`, `src/` | Практика студента, smoke-скрипты, демонстрации, helper-логика | | Internal planning | `plans/` | Внутренние living docs по разработке материалов | @@ -28,8 +31,9 @@ | --- | --- | --- | | `docker-compose.yml` | Реальный состав сервисов, контейнеров, сетей, портов и зависимостей | Учебные пояснения, которые не нужны для запуска | | `spark/`, `trino/`, `jupyter/` | Конкретные runtime-конфиги и образы | Описание программы курса | -| `README.md` | Верхнеуровневое объяснение архитектуры стенда и состава репозитория | Пошаговый student onboarding во всех деталях | +| `README.md` | Верхнеуровневое объяснение репозитория, архитектуры и точек входа | Пошаговый student onboarding во всех деталях и low-level runtime reference | | `START_HERE.md` | Первый маршрут студента: prerequisites, запуск, первые UI, первый ноутбук, базовая диагностика | Полный PRD курса или подробный бэклог модулей | +| `docs/stack_reference.md` | Технический reference стенда: сервисы, порты, доступ, reset, smoke-тесты | Роль основного onboarding-документа или описание всей программы курса | | `docs/course_prd.md` | Product scope, аудитория, learning outcomes, dataset strategy, out of scope | Технические мелочи запуска контейнеров | | `docs/course_program.md` | Модульная структура курса, состав материалов, checkpoints | Подробные docker-команды и legacy-лабы | | `notebooks/` | Каноническая практическая часть курса | Длинные инфраструктурные HOWTO | @@ -57,6 +61,7 @@ - `docker-compose.yml`; - `README.md`; - `START_HERE.md`; +- `docs/stack_reference.md`; - затронутые команды в `src/`, ноутбуках и планах. ### Если меняется маршрут студента diff --git a/docs/stack_reference.md b/docs/stack_reference.md new file mode 100644 index 0000000..1c078b6 --- /dev/null +++ b/docs/stack_reference.md @@ -0,0 +1,172 @@ +# Технический reference стенда + +Этот документ описывает сам стенд как runtime-среду: сервисы, порты, доступ, основные команды и smoke-тесты. + +Если нужен первый student onboarding, используй [START_HERE.md](../START_HERE.md). Если нужна программа курса, используй [course_program.md](./course_program.md). + +## Состав сервисов + +| Сервис | Контейнер | Порт на хосте | Назначение | +| --- | --- | --- | --- | +| Spark master | `spark-master` | `7077`, `8080` | мастер Spark и его UI | +| Spark worker 1 | `spark-worker-1` | `8081` | первый worker Spark | +| Spark worker 2 | `spark-worker-2` | `8082` | второй worker Spark | +| Trino | `trino` | `8090` | SQL engine и Web UI | +| MinIO API | `minio` | `9000` | S3-compatible endpoint | +| MinIO Console | `minio` | `9001` | веб-консоль бакетов и объектов | +| PostgreSQL | `postgres-iceberg` | `5432` | JDBC-каталог Iceberg | +| JupyterLab | `jupyter` | `8888` | практические ноутбуки | + +## Основные команды + +Все команды выполняются из корня репозитория. + +### Сборка и запуск + +```bash +docker compose build +docker compose up -d +docker compose ps +``` + +### Логи + +```bash +docker compose logs -f spark-master +docker compose logs -f trino +docker compose logs -f minio +docker compose logs -f jupyter +``` + +### Остановка и reset + +```bash +docker compose down +docker compose down -v +``` + +`down -v` удаляет volumes и возвращает стенд в чистое состояние. + +## Доступ к сервисам + +### Spark + +- Master UI: `http://localhost:8080` +- Worker UI: `http://localhost:8081` и `http://localhost:8082` +- Spark master endpoint внутри сети compose: `spark://spark-master:7077` + +Пример запуска smoke-скрипта: + +```bash +docker compose exec spark-master \ + /opt/spark/bin/spark-submit /opt/src/spark/cluster_smoke.py +``` + +### Trino + +- Web UI: `http://localhost:8090` + +CLI внутри контейнера: + +```bash +docker compose exec -it trino trino --catalog lakehouse +``` + +Примеры первых команд: + +```sql +SHOW CATALOGS; +SHOW SCHEMAS FROM lakehouse; +SHOW TABLES FROM lakehouse.default; +``` + +### MinIO + +- S3 endpoint: `http://localhost:9000` +- Console: `http://localhost:9001` +- логин: `minioadmin` +- пароль: `minioadmin` + +Бакет `lakehouse` обычно создаётся автоматически контейнером `minio-init`. + +### PostgreSQL + +Подключение с хоста: + +```bash +psql -h localhost -p 5432 -U iceberg -d iceberg +``` + +Служебные таблицы JDBC-каталога создаёт `iceberg-catalog-init`. + +Если нужен повторный запуск инициализации: + +```bash +docker compose run --rm iceberg-catalog-init +``` + +### JupyterLab + +- адрес: `http://localhost:8888` +- `./notebooks` смонтирован как `/opt/work` +- `./src` смонтирован read-only как `/opt/src` +- `PYTHONPATH=/opt/src` + +Первый ноутбук курса: `notebooks/01_environment_and_smoke_test.ipynb`. + +## Как связаны Spark, Trino, PostgreSQL и MinIO + +- `Spark` использует каталог `lakehouse` через `JdbcCatalog`. +- `Trino` использует тот же каталог `lakehouse` через `iceberg.jdbc-catalog`. +- метаданные таблиц лежат в `PostgreSQL`; +- данные и metadata-файлы Iceberg лежат в `MinIO` в бакете `lakehouse`. + +Именно поэтому таблица, созданная в `Spark`, может читаться в `Trino` без копирования данных. + +## Где лежат ключевые конфиги + +| Файл | Что задаёт | +| --- | --- | +| `docker-compose.yml` | состав сервисов, порты, volumes, init-контейнеры | +| `spark/spark-defaults.conf` | Spark catalog `lakehouse`, `s3a`, Iceberg extensions | +| `trino/catalog/lakehouse.properties` | каталог Trino `lakehouse`, JDBC и S3-доступ | +| `spark/Dockerfile` | образ Spark с Iceberg, S3A и Python-зависимостями | +| `jupyter/Dockerfile` | образ JupyterLab на базе Spark | + +## Smoke-тесты + +### 1. Проверка, что Spark-кластер жив + +```bash +docker compose exec spark-master \ + /opt/spark/bin/spark-submit /opt/src/spark/cluster_smoke.py +``` + +### 2. Проверка Spark -> Trino через общий каталог + +```bash +docker compose cp src/spark/iceberg_smoke.py spark-master:/tmp/ +docker compose cp src/trino/iceberg_smoke.sql trino:/tmp/ +docker compose exec spark-master /opt/spark/bin/spark-submit /tmp/iceberg_smoke.py +docker compose exec trino trino --file /tmp/iceberg_smoke.sql +``` + +Ожидаемый результат: + +- в Spark создаётся `lakehouse.default.spark_trino_smoke`; +- в Trino видна та же таблица; +- выборка возвращает строку `1, from_spark`. + +Опциональная очистка: + +```bash +docker compose exec spark-master \ + /opt/spark/bin/spark-sql -e "DROP TABLE IF EXISTS lakehouse.default.spark_trino_smoke" +``` + +## Когда какой документ использовать + +- `README.md` — чтобы понять, что это за репозиторий и куда идти дальше. +- `START_HERE.md` — чтобы впервые поднять стенд и пройти Модуль 1. +- `stack_reference.md` — чтобы быстро вспомнить порты, команды, точки доступа и smoke-тесты. +- `course_program.md` — чтобы понять учебную траекторию дальше первого модуля.