docs(readme): разделены student-facing и внутренние документы

- Зачем:
  - нужно убрать смешение маршрута студента с внутренними документами сопровождения репозитория.
- Что:
  - переработан 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 на согласованность маршрута и аудиторий.
This commit is contained in:
2026-03-07 00:38:26 +03:00
parent d1bcd63bf1
commit 3f76d66ed1
4 changed files with 233 additions and 350 deletions
+3 -2
View File
@@ -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`.
- Не дублируй крупные фрагменты между документами, если можно сослаться на канонический файл.
+51 -346
View File
@@ -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` или <https://creativecommons.org/licenses/by/4.0/>.
Материалы этого репозитория лицензированы на условиях Creative Commons Attribution 4.0 International (`CC BY 4.0`).
См. [LICENSE](./LICENSE).
+7 -2
View File
@@ -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/`, ноутбуках и планах.
### Если меняется маршрут студента
+172
View File
@@ -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` — чтобы понять учебную траекторию дальше первого модуля.