Files
mini-lakehouse-lab/docs/stack_reference.md
T

20 KiB
Raw Blame History

Технический reference стенда

Этот документ описывает сам стенд как runtime-среду: сервисы, порты, доступ, основные команды и smoke-тесты.

Если нужен первый student onboarding, используй START_HERE.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
VS Code в браузере (code-server) ide 8889 основной интерфейс для ноутбуков и терминала
JupyterLab jupyter 8888 запасной интерфейс для тех же ноутбуков

Основные команды

Все команды выполняются в терминале хоста из корня репозитория. Для первого запуска и настройки прав используй START_HERE, для продолжения работы — памятку учащегося.

Сборка и запуск

docker compose pull minio minio-init postgres trino
docker compose build
docker compose up -d
docker compose ps -a

Логи

docker compose logs -f spark-master
docker compose logs -f trino
docker compose logs -f minio
docker compose logs -f jupyter
docker compose logs -f ide

Остановка и reset

Действие Команда Что происходит с данными
Пауза до следующего занятия docker compose stop Контейнеры остановлены, файлы и volumes сохранены
Продолжение docker compose up -d Сервисы запускаются с прежними данными
Удаление контейнеров и сети docker compose down Volumes и файлы на хосте сохраняются, состояние внутри удаленных контейнеров теряется
Полный сброс учебных данных См. отдельную инструкцию Удаляются MinIO volume и каталог PostgreSQL

Переменные Python и живые Spark-сессии после остановки нужно создать заново.

Ресурсы и проверенная среда

Актуальный бюджет для учащегося приведен в системных требованиях. Он учитывает одновременную работу двух Spark worker-ов, драйвера в IDE, Trino, MinIO и PostgreSQL. У каждого worker-а в Compose указаны 2 CPU и 2 ГБ для приложений Spark; это не предел потребления всей JVM или контейнера. Потребление при простое не показывает пик во время урока.

Проверка 19 октября 2026 года: Linux x86_64, Docker Engine, 6 CPU и около 11,1 ГиБ памяти, видимых Docker. Выполнены первый ноутбук в Chromium и проверка Spark → Iceberg → Trino. Прогона всех восьми модулей с измерением пиков памяти и диска не было; минимальный объем RAM не установлен. Docker Desktop и ARM64 в этой проверке не запускались.

Размеры локально собранных образов на этой машине: Spark — около 3,37 ГБ, Jupyter — 3,72 ГБ, IDE — 4,90 ГБ. Jupyter включает слои Spark, IDE включает слои Jupyter: складывать эти три числа для оценки места неправильно. IDE добавляет около 1,18 ГБ. IDE вместе с отдельными образами Trino, PostgreSQL и MinIO дает около 8,1 ГБ до учета кэша сборки, данных и особенностей хранилища Docker. Поэтому перед первой сборкой нужен запас места сверх размера готовых образов.

Доступ к сервисам

Spark

  • Master UI: http://localhost:8080
  • Worker UI: http://localhost:8081 и http://localhost:8082
  • Адрес Spark master внутри сети Docker Compose: spark://spark-master:7077

Адрес кластера (spark.master) и настройки доступа к Iceberg и MinIO заданы в spark/spark-defaults.conf. Docker подключает этот файл к контейнеру Jupyter как /opt/spark/conf/spark-defaults.conf.

При первом вызове getOrCreate() Spark читает настройки и создает сессию. Повторный вызов использует уже работающую сессию. Если изменил адрес кластера или настройки в файле, перезапусти ядро ноутбука и снова выполни ячейки с импортами и созданием сессии.

Фактический master и имя приложения доступны через spark.sparkContext.master и .appName. Текущие SQL-настройки можно прочитать через spark.conf.get(...). В Spark 3.5.1 spark.sql.session.timeZone меняется через spark.conf.set(...) без остановки сессии. Для нового имени приложения нужен новый SparkContext.

Пример запуска smoke-скрипта:

docker compose exec ide python3 /opt/src/spark/cluster_smoke.py

Trino

  • Web UI: http://localhost:8090

CLI внутри контейнера:

docker compose exec -it trino trino --catalog lakehouse

Примеры первых команд:

SHOW CATALOGS;
SHOW SCHEMAS FROM lakehouse;
SHOW TABLES FROM lakehouse.default;

Подключение через DBeaver:

  • Host: localhost, Port: 8090, Catalog: lakehouse, User: любая строка, Password: нет.
  • Driver: Trino (встроен в DBeaver).
  • Проверка: SHOW SCHEMAS FROM lakehouse;.

MinIO

  • S3 endpoint: http://localhost:9000
  • Console: http://localhost:9001
  • логин: minioadmin
  • пароль: minioadmin

Стенд использует готовый образ coollabsio/minio:RELEASE.2025-04-22T22-12-26Z. Это сторонняя сборка из официальных исходников MinIO, которая содержит сервер и клиент mc версии RELEASE.2025-08-13T08-35-41Z. Версия сервера предшествует изменению встроенной консоли в мае 2025 года. Образ подходит для локального курса; это историческая версия без текущих обновлений, не production-конфигурация.

В Compose закреплён digest индекса для AMD64 и ARM64: sha256:a4938f37f1be1841b8e7b627ad0207b265345fd0d063e42d7410c78af0e63e68. Сервисы minio и minio-init используют один образ. Компиляция MinIO и установка Go не нужны. По умолчанию образ скачивается из GHCR без авторизации. Автор публикует тот же digest в Docker Hub; резервный источник выбирается через MINIO_REGISTRY=docker.io в .env. Подробности — в инструкции по доступу к репозиториям.

Бакет lakehouse обычно создаётся автоматически контейнером minio-init.

PostgreSQL

Подключение с хоста:

psql -h localhost -p 5432 -U iceberg -d iceberg

Служебные таблицы JDBC-каталога создаёт iceberg-catalog-init.

Если нужен повторный запуск инициализации:

docker compose run --rm iceberg-catalog-init

VS Code в браузере

Открой http://localhost:8889. Сервис ide запускает code-server с установленными расширениями Python и Jupyter. Python, ipykernel, Java, PySpark и зависимости курса уже находятся в образе. Локальный Python или venv не нужен.

В рабочей области доступны ноутбуки, примеры из src/ и документация. Репозиторий смонтирован в /opt/course только для чтения, а его каталог notebooks/ — для чтения и записи. Так относительные ссылки между документами и ноутбуками работают и внутри IDE. Пути /opt/work, /opt/src, /opt/data также доступны примерам курса. Открой 01_environment_and_smoke_test.ipynb, нажми Select Kernel → Python Environments и выбери /usr/bin/python3. Это Python внутри контейнера IDE. Расширение Jupyter запускает ядро там же; адрес отдельного Jupyter Server вводить не требуется.

Порт IDE опубликован только на 127.0.0.1, без пароля, для одного пользователя. Открывай именно localhost или 127.0.0.1: браузер считает их доверенным контекстом даже по HTTP. Notebook webview использует service worker; при обращении по обычному HTTP к IP сервера или имени в локальной сети этот механизм может быть недоступен. Это ограничение secure context, отдельное от CORS и XSRF. См. secure contexts и webviews в code-server.

Для стенда на удалённой машине используй SSH-туннель:

ssh -N -L 8889:127.0.0.1:8889 user@host

Затем открой http://localhost:8889 на своём компьютере. Прямой доступ по публичному адресу не входит в эту конфигурацию.

Образы собираются в порядке spark-master → jupyter → ide через Compose additional_contexts (нужен Docker Compose 2.17+ и BuildKit). Версии code-server и расширений зафиксированы в ide/Dockerfile; расширения скачиваются при сборке. Автоматическое обновление расширений отключено, чтобы повторный запуск использовал проверенные версии.

JupyterLab

  • адрес: http://localhost:8888
  • порт опубликован только на 127.0.0.1 хоста;
  • аутентификация и XSRF-проверка отключены для локального одно-пользовательского стенда;
  • через VS Code Remote-SSH используй Existing Jupyter Server с адресом http://127.0.0.1:8888/ без token;
  • ./notebooks смонтирован как /opt/work
  • ./src смонтирован read-only как /opt/src
  • ./data смонтирован read-only как /opt/data
  • PYTHONPATH=/opt/src

JupyterLab остаётся запасным интерфейсом. Он редактирует те же файлы, но запускает отдельные ядра: переменные Python между IDE и JupyterLab не общие. Перед сменой интерфейса сохрани ноутбук и останови его ядро.

Первый ноутбук курса: notebooks/01_environment_and_smoke_test.ipynb.

Для Модуля 3 локально скачанный data bundle должен лежать на хосте в ./data/nyc_taxi и будет доступен внутри Jupyter по пути /opt/data/nyc_taxi.

Как связаны 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 master, catalog lakehouse, s3a, Iceberg extensions
trino/catalog/lakehouse.properties каталог Trino lakehouse, JDBC и S3-доступ
spark/Dockerfile образ Spark с Iceberg, S3A и Python-зависимостями
jupyter/Dockerfile образ JupyterLab на базе Spark
ide/Dockerfile code-server и расширения на базе образа Jupyter
ide/lakehouse.code-workspace папки рабочей области и настройки Python
docs/network_access.md источники образов и зависимостей, резервный registry и диагностика сети
docs/study_workflow.md повседневная работа, сохранение состояния и диагностика ошибок

Smoke-тесты

Браузерная IDE и Jupyter-ноутбук

На Linux с Docker Engine, после запуска стенда:

bash tests/browser_ide.sh

Проверка запускает Chromium в отдельном контейнере и проходит путь студента: доверие рабочей области → открытие копии Модуля 1 → выбор Python → Run All → вывод Spark в webview → сохранение → повторное открытие. Затем проверяет, что все кодовые ячейки выполнились без ошибок и результат сохранился. Исходный ноутбук не меняется. Скриншот остаётся в каталоге /tmp/lakehouse-browser-check.*, путь печатается перед запуском. Docker Desktop этим скриптом не проверяется: он использует Linux host networking.

Для проверки отдельного стенда можно задать COMPOSE_FILE и IDE_URL; по умолчанию тест использует текущий Compose-проект и http://localhost:8889.

1. Проверка, что Spark-кластер жив

docker compose exec ide python3 /opt/src/spark/cluster_smoke.py

2. Проверка Spark -> Trino через общий каталог

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.

Опциональная очистка:

docker compose exec spark-master \
  /opt/spark/bin/spark-sql -e "DROP TABLE IF EXISTS lakehouse.default.spark_trino_smoke"

Краткая шпаргалка

Ключевые S3-пути курса

Путь Назначение
s3a://lakehouse/raw/nyc_taxi/ raw-зона: исходные Parquet и CSV
s3a://lakehouse/warehouse/bronze/ bronze-таблицы Iceberg
s3a://lakehouse/warehouse/silver/ silver-таблицы Iceberg

Основные таблицы курса

Таблица Создаётся в
lakehouse.bronze.nyc_taxi_yellow Модуль 4
lakehouse.bronze.taxi_zone_lookup Модуль 4 (самостоятельное задание)
lakehouse.silver.nyc_taxi_yellow Модуль 5

Часто используемые Spark SQL

-- Просмотр структуры каталога
SHOW TABLES IN lakehouse.bronze;

-- Метаданные Iceberg
SELECT * FROM <table>.snapshots;
SELECT * FROM <table>.files;

-- Обслуживание (Модуль 8)
CALL lakehouse.system.rewrite_data_files(table => '<namespace>.<table>');
CALL lakehouse.system.expire_snapshots(
    table => '<namespace>.<table>',
    older_than => TIMESTAMP '<cutoff>',
    retain_last => N
);

-- Rollback (Модуль 7)
CALL lakehouse.system.rollback_to_snapshot(table => '<namespace>.<table>', snapshot_id => <id>);

-- Time travel (Модуль 7)
SELECT * FROM <table> VERSION AS OF <snapshot_id>;

Для expire_snapshots подставь в <cutoff> границу хранения истории в часовом поясе Spark-сессии. retain_last сохраняет минимум N последних snapshot-ов в цепочке предков текущего состояния, а не ограничивает всю историю числом N. Получение границы времени для учебного примера показано в Модуле 8, Секции 4.

Часто используемые Trino SQL

SHOW SCHEMAS FROM lakehouse;
SHOW TABLES FROM lakehouse.silver;
DESCRIBE lakehouse.silver.nyc_taxi_yellow;

-- Time travel (синтаксис Trino)
SELECT * FROM <table> FOR VERSION AS OF <snapshot_id>;

Монтирование (хост → контейнер)

Хост Контейнер Режим
./notebooks /opt/work read-write
./src /opt/src read-only
./data /opt/data read-only

Когда какой документ использовать

  • README.md — чтобы понять, что это за репозиторий и куда идти дальше.
  • START_HERE.md — чтобы впервые поднять стенд и пройти Модуль 1.
  • study_workflow.md — чтобы продолжить занятие, сохранить результат и разобраться с ошибкой.
  • stack_reference.md — чтобы быстро вспомнить порты, команды, точки доступа, шпаргалку и smoke-тесты.
  • course_program.md — чтобы понять учебную траекторию дальше первого модуля.
  • glossary.md — чтобы вернуться к определению термина (storage, catalog, compute, snapshot и др.).
  • mentor_notes.md — заметки для ведения курса с ментором (опционально).