23 KiB
Технический 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.configheap 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/dataPYTHONPATH=/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— заметки для ведения курса с ментором (опционально).