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:
@@ -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`.
|
||||
- Не дублируй крупные фрагменты между документами, если можно сослаться на канонический файл.
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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/`, ноутбуках и планах.
|
||||
|
||||
### Если меняется маршрут студента
|
||||
|
||||
@@ -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` — чтобы понять учебную траекторию дальше первого модуля.
|
||||
Reference in New Issue
Block a user