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

23 KiB
Raw Permalink 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. Затем Trino проверен с лимитом контейнера 2 ГиБ и heap 1 ГиБ на трех месяцах Taxi: 9 554 778 строк bronze, 9 418 184 строк silver и 265 зон. Запросы Модуля 6 и дополнительный JOIN со справочником прошли; агрегаты и JOIN сверены со Spark. Пик памяти контейнера Trino по cgroup составил около 1,25 ГиБ, событий OOM и перезапусков не было.

Наблюдавшийся суммарный пик памяти контейнеров без неактивного файлового кэша составил около 5,44 ГиБ. Это измерение выбранного сценария, а не проверка всей среды под общим лимитом 8 ГБ: память Docker daemon, ядра и других процессов Linux/WSL2 в сумму не входит. Прогона всех восьми модулей под таким лимитом не было. 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
  • Контейнер ограничен 2 ГиБ RAM (mem_limit: 2g). memswap_limit: 2g отключает swap для него: одинаковое значение задает общий предел RAM + swap.
  • В trino/jvm.config heap Java начинается с 512 МиБ и может вырасти до 1 ГиБ (-Xms512M, -Xmx1G). Остальная память контейнера оставлена для потоков, служебных структур JVM и буферов вне heap.

Эти ограничения относятся к Trino; у всего Compose-проекта общего лимита памяти нет. Если контейнер достигнет жесткого предела, он может быть завершен системой. Увеличение только heap без изменения бюджета контейнера уменьшает запас для памяти вне heap. См. лимиты Compose и настройку JVM Trino.

После обновления этих файлов примени настройки из терминала хоста:

docker compose up -d --no-deps --force-recreate trino
docker compose ps -a trino

Дождись healthy. Эта операция пересоздает только Trino и применяет в том числе изменения содержимого jvm.config; таблицы остаются в MinIO и PostgreSQL.

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-доступ
trino/jvm.config JVM Trino: heap до 1 ГиБ внутри контейнера с лимитом 2 ГиБ
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 — заметки для ведения курса с ментором (опционально).