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` — первый маршрут для студента до запуска ноутбуков.
|
- `START_HERE.md` — первый маршрут для студента до запуска ноутбуков.
|
||||||
|
- `docs/stack_reference.md` — технический reference по сервисам, портам, доступу и smoke-тестам.
|
||||||
- `docs/course_prd.md` — рамки курса, learning outcomes, scope и out of scope.
|
- `docs/course_prd.md` — рамки курса, learning outcomes, scope и out of scope.
|
||||||
- `docs/course_program.md` — модульная структура курса и состав учебных материалов.
|
- `docs/course_program.md` — модульная структура курса и состав учебных материалов.
|
||||||
- `docs/maintainer_guide.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/`.
|
- Если меняются scope курса, learning outcomes или модульная структура, обновляй `docs/course_prd.md` и `docs/course_program.md`, а не только `plans/`.
|
||||||
- Поддерживай согласованный маршрут `README -> START_HERE -> docs/course_program.md -> notebooks/src`.
|
- Поддерживай согласованный маршрут `README -> START_HERE -> docs/course_program.md -> notebooks/src`.
|
||||||
- Не дублируй крупные фрагменты между документами, если можно сослаться на канонический файл.
|
- Не дублируй крупные фрагменты между документами, если можно сослаться на канонический файл.
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
# Учебный Lakehouse-стенд (Trino + Spark + Iceberg + MinIO)
|
# Lakehouse без магии: локальный стенд и учебные материалы
|
||||||
|
|
||||||
Учебный стенд для демонстрации **Lakehouse-архитектуры** на одном ноутбуке:
|
Этот репозиторий объединяет:
|
||||||
|
|
||||||
- объектное хранилище S3-класса (MinIO),
|
- локальный Lakehouse-стенд на `Spark + Trino + Iceberg + MinIO + PostgreSQL`;
|
||||||
- движок запросов Trino,
|
- учебный курс `Lakehouse без магии`, который использует этот стенд как практическую среду;
|
||||||
- Spark для batch/ETL и интерактивных экспериментов,
|
- стартовые ноутбуки и demo-скрипты для первых экспериментов.
|
||||||
- формат таблиц Iceberg,
|
|
||||||
- JDBC-каталог (PostgreSQL) для метаданных Iceberg в Trino,
|
|
||||||
- конфиг Spark, заточенный под работу с Iceberg + S3.
|
|
||||||
|
|
||||||
Стенд ориентирован на обучение менти и быструю демонстрацию концепции Lakehouse: разделение **storage / compute / catalog** без лишней обвязки (Hive Metastore, полноценный Hadoop-кластер и т.п.).
|
Репозиторий рассчитан не на «универсальную платформу для всего», а на понятную локальную песочницу, где можно руками пройти путь от запуска стенда до чтения одной и той же Iceberg-таблицы из `Spark` и `Trino`.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Архитектура
|
## Архитектура
|
||||||
|
|
||||||
@@ -36,363 +31,73 @@ graph LR
|
|||||||
T <--> P
|
T <--> P
|
||||||
```
|
```
|
||||||
|
|
||||||
**Основные идеи:**
|
Коротко по ролям:
|
||||||
|
|
||||||
* **Данные** (Parquet-файлы + служебные каталоги Iceberg) лежат в бакете MinIO (`s3a://lakehouse/warehouse/...`).
|
- `MinIO` хранит данные и служебные файлы Iceberg.
|
||||||
* **Метаданные** Iceberg хранятся в PostgreSQL (JDBC-каталог `lakehouse`).
|
- `PostgreSQL` хранит метаданные JDBC-каталога `lakehouse`.
|
||||||
* **Spark и Trino** используют один и тот же JDBC-каталог: таблицы, созданные в Spark, доступны в Trino, и наоборот.
|
- `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
|
```bash
|
||||||
docker compose build
|
docker compose build
|
||||||
```
|
|
||||||
|
|
||||||
Будут собраны кастомные образы Spark/Jupyter с зависимостями Iceberg, S3A, JDBC-драйвером Postgres и Python-библиотеками.
|
|
||||||
|
|
||||||
### 2. Поднять стенд
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose up -d
|
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
|
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
|
Полный onboarding, диагностика и reset-сценарии находятся в `START_HERE.md`.
|
||||||
docker compose down -v
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
## Как устроен репозиторий
|
||||||
|
|
||||||
## Доступ к сервисам
|
| Где | Что лежит |
|
||||||
|
| --- | --- |
|
||||||
|
| `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
|
- [docs/stack_reference.md](./docs/stack_reference.md) — сервисы, порты, доступ, reset, smoke tests;
|
||||||
docker exec -it trino trino \
|
- [spark/spark-defaults.conf](./spark/spark-defaults.conf) — конфигурация Spark-каталога `lakehouse`;
|
||||||
--server http://localhost:8080 \
|
- [trino/catalog/lakehouse.properties](./trino/catalog/lakehouse.properties) — конфигурация каталога Trino;
|
||||||
--catalog lakehouse
|
- [docker-compose.yml](./docker-compose.yml) — фактический состав стенда.
|
||||||
```
|
|
||||||
|
|
||||||
Проверка:
|
|
||||||
|
|
||||||
```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`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Лицензия
|
## Лицензия
|
||||||
|
|
||||||
Материалы этого репозитория лицензированы на условиях Creative Commons Attribution 4.0 International (CC BY 4.0).
|
Материалы этого репозитория лицензированы на условиях Creative Commons Attribution 4.0 International (`CC BY 4.0`).
|
||||||
См. файл `LICENSE` или <https://creativecommons.org/licenses/by/4.0/>.
|
См. [LICENSE](./LICENSE).
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
Этот документ нужен, чтобы не раздувать `AGENTS.md` и не дублировать изменчивый контекст проекта в нескольких местах.
|
Этот документ нужен, чтобы не раздувать `AGENTS.md` и не дублировать изменчивый контекст проекта в нескольких местах.
|
||||||
|
|
||||||
|
Это внутренний документ сопровождения репозитория. Для прохождения курса и первого запуска стенда он обычно не нужен.
|
||||||
|
|
||||||
## Что это за репозиторий сейчас
|
## Что это за репозиторий сейчас
|
||||||
|
|
||||||
Репозиторий состоит из двух тесно связанных слоёв:
|
Репозиторий состоит из двух тесно связанных слоёв:
|
||||||
@@ -16,7 +18,8 @@
|
|||||||
| Зона | Где лежит | Назначение |
|
| Зона | Где лежит | Назначение |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Runtime / stand | `docker-compose.yml`, `spark/`, `trino/`, `jupyter/` | Топология сервисов, образы, конфиги, порты |
|
| 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, структура модулей |
|
| Course definition | `docs/course_prd.md`, `docs/course_program.md` | Границы курса, learning outcomes, структура модулей |
|
||||||
| Practice materials | `notebooks/`, `src/` | Практика студента, smoke-скрипты, демонстрации, helper-логика |
|
| Practice materials | `notebooks/`, `src/` | Практика студента, smoke-скрипты, демонстрации, helper-логика |
|
||||||
| Internal planning | `plans/` | Внутренние living docs по разработке материалов |
|
| Internal planning | `plans/` | Внутренние living docs по разработке материалов |
|
||||||
@@ -28,8 +31,9 @@
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `docker-compose.yml` | Реальный состав сервисов, контейнеров, сетей, портов и зависимостей | Учебные пояснения, которые не нужны для запуска |
|
| `docker-compose.yml` | Реальный состав сервисов, контейнеров, сетей, портов и зависимостей | Учебные пояснения, которые не нужны для запуска |
|
||||||
| `spark/`, `trino/`, `jupyter/` | Конкретные runtime-конфиги и образы | Описание программы курса |
|
| `spark/`, `trino/`, `jupyter/` | Конкретные runtime-конфиги и образы | Описание программы курса |
|
||||||
| `README.md` | Верхнеуровневое объяснение архитектуры стенда и состава репозитория | Пошаговый student onboarding во всех деталях |
|
| `README.md` | Верхнеуровневое объяснение репозитория, архитектуры и точек входа | Пошаговый student onboarding во всех деталях и low-level runtime reference |
|
||||||
| `START_HERE.md` | Первый маршрут студента: prerequisites, запуск, первые UI, первый ноутбук, базовая диагностика | Полный PRD курса или подробный бэклог модулей |
|
| `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_prd.md` | Product scope, аудитория, learning outcomes, dataset strategy, out of scope | Технические мелочи запуска контейнеров |
|
||||||
| `docs/course_program.md` | Модульная структура курса, состав материалов, checkpoints | Подробные docker-команды и legacy-лабы |
|
| `docs/course_program.md` | Модульная структура курса, состав материалов, checkpoints | Подробные docker-команды и legacy-лабы |
|
||||||
| `notebooks/` | Каноническая практическая часть курса | Длинные инфраструктурные HOWTO |
|
| `notebooks/` | Каноническая практическая часть курса | Длинные инфраструктурные HOWTO |
|
||||||
@@ -57,6 +61,7 @@
|
|||||||
- `docker-compose.yml`;
|
- `docker-compose.yml`;
|
||||||
- `README.md`;
|
- `README.md`;
|
||||||
- `START_HERE.md`;
|
- `START_HERE.md`;
|
||||||
|
- `docs/stack_reference.md`;
|
||||||
- затронутые команды в `src/`, ноутбуках и планах.
|
- затронутые команды в `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