fix(trino): bound memory for the learning stack

This commit is contained in:
ddadmin committed 2026-10-19 10:47:40 +02:00
1 parent 21f3570b89
commit 863d658a5f
6 files changed
+177 -11

No files matched your search

+2 -1
View File
@@ -70,7 +70,8 @@ graph TB
остановка, продолжение работы и диагностика. остановка, продолжение работы и диагностика.
Для одного учащегося рекомендуем компьютер с 16 ГБ RAM, не менее 4 CPU и Для одного учащегося рекомендуем компьютер с 16 ГБ RAM, не менее 4 CPU и
10 ГБ памяти, доступных Docker, а также от 20 ГБ свободного места перед сборкой. ориентировочно 8 ГБ памяти для Docker, а также от 20 ГБ свободного места перед сборкой.
Trino ограничен 2 ГиБ памяти контейнера и 1 ГиБ Java heap.
Подробности и границы проверки — в [системных требованиях](./START_HERE.md#системные-требования). Подробности и границы проверки — в [системных требованиях](./START_HERE.md#системные-требования).
Краткий запуск из корня репозитория после подготовки по `START_HERE`: Краткий запуск из корня репозитория после подготовки по `START_HERE`:
+13 -7
View File
@@ -39,15 +39,21 @@
| Ресурс | Рекомендация | Что проверить | | Ресурс | Рекомендация | Что проверить |
| --- | --- | --- | | --- | --- | --- |
| Процессор | Не менее 4 CPU, доступных Docker | В Docker Desktop/WSL2 может стоять меньший лимит | | Процессор | Не менее 4 CPU, доступных Docker | В Docker Desktop/WSL2 может стоять меньший лимит |
| Память Docker | Не менее 10 ГБ RAM | Это память для контейнеров, а не общий объем памяти компьютера | | Память Docker | Ориентир — 8 ГБ RAM; 10 ГБ дают дополнительный запас | Это память для среды Docker, а не общий объем памяти компьютера |
| Память компьютера | 16 ГБ RAM или больше | Оставь память ОС, браузеру и другим приложениям | | Память компьютера | 16 ГБ RAM или больше | Оставь память ОС, браузеру и другим приложениям |
| Свободное место | Не менее 20 ГБ перед первой сборкой; 30 ГБ с запасом | На диске Docker и в папке репозитория: образы, кэш сборки, исходные данные и таблицы | | Свободное место | Не менее 20 ГБ перед первой сборкой; 30 ГБ с запасом | На диске Docker и в папке репозитория: образы, кэш сборки, исходные данные и таблицы |
Это рекомендуемый бюджет, а не измеренный минимальный порог. Полный курс на Это рекомендуемый бюджет для одного активного ноутбука, а не измеренный минимум.
машине с 8 ГБ RAM не проверен. В Docker Desktop проверь На Windows с WSL2 по умолчанию доступно 50% RAM компьютера: при 16 ГБ это 8 ГБ
[лимиты ресурсов](https://docs.docker.com/desktop/settings-and-maintenance/settings/#resources); для всей WSL2, включая Docker. Лимит можно настроить, это не аппаратное
для режима WSL2 лимиты задаются у виртуальной машины WSL2. Место внутри диска ограничение. См. [настройки WSL2](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#main-wsl-settings)
Docker и свободное место на диске компьютера — отдельные ограничения. и [ресурсы Docker Desktop](https://docs.docker.com/desktop/settings-and-maintenance/settings/#resources).
Trino ограничен 2 ГиБ памяти контейнера и 1 ГиБ Java heap. Проверка запросов
на данных курса описана в [справочнике](./docs/stack_reference.md#ресурсы-и-проверенная-среда).
Полный курс под общим жестким лимитом Docker 8 ГБ пока не проверен. В WSL2 часть
памяти также нужна самой Linux-среде; закрой другие тяжелые задачи на время урока.
Место внутри диска Docker и свободное место на диске компьютера — отдельные ограничения.
С добавлением VS Code образ окружения вырос примерно на 1,2 ГБ относительно С добавлением VS Code образ окружения вырос примерно на 1,2 ГБ относительно
Jupyter; базовые слои у них общие. MinIO скачивается готовым, компилировать его Jupyter; базовые слои у них общие. MinIO скачивается готовым, компилировать его
@@ -74,7 +80,7 @@ docker compose config --quiet
В `docker version` должны быть разделы Client и Server, версия Compose — не В `docker version` должны быть разделы Client и Server, версия Compose — не
ниже 2.17. `docker info` показывает ресурсы, которые видит Docker; память дана ниже 2.17. `docker info` показывает ресурсы, которые видит Docker; память дана
в байтах (10 ГБ — примерно 10 000 000 000 байт). Последняя команда при успехе в байтах (8 ГиБ — 8 589 934 592 байта). Последняя команда при успехе
ничего не печатает. Если Docker не отвечает или конфигурация не читается, ничего не печатает. Если Docker не отвечает или конфигурация не читается,
исправь эту ошибку до сборки. исправь эту ошибку до сборки.
+4
View File
@@ -231,6 +231,9 @@ services:
image: trinodb/trino:478 image: trinodb/trino:478
container_name: trino container_name: trino
hostname: trino hostname: trino
# Heap JVM ограничен отдельно в trino/jvm.config; остальное — запас вне heap.
mem_limit: 2g
memswap_limit: 2g
networks: networks:
- spark-net - spark-net
depends_on: depends_on:
@@ -245,6 +248,7 @@ services:
- "8090:8080" # Web UI Trino - "8090:8080" # Web UI Trino
volumes: volumes:
- ./trino/catalog:/etc/trino/catalog:ro - ./trino/catalog:/etc/trino/catalog:ro
- ./trino/jvm.config:/etc/trino/jvm.config:ro
networks: networks:
spark-net: spark-net:
+34 -3
View File
@@ -65,9 +65,18 @@ MinIO и PostgreSQL. У каждого worker-а в Compose указаны 2 CPU
Проверка 19 октября 2026 года: Linux x86_64, Docker Engine, 6 CPU и около Проверка 19 октября 2026 года: Linux x86_64, Docker Engine, 6 CPU и около
11,1 ГиБ памяти, видимых Docker. Выполнены первый ноутбук в Chromium и проверка 11,1 ГиБ памяти, видимых Docker. Выполнены первый ноутбук в Chromium и проверка
Spark → Iceberg → Trino. Прогона всех восьми модулей с измерением пиков памяти Spark → Iceberg → Trino. Затем Trino проверен с лимитом контейнера 2 ГиБ и heap
и диска не было; минимальный объем RAM не установлен. Docker Desktop и ARM64 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 в этой проверке не запускались.
Методика и результаты сохранены в [отчете проверки](../plans/trino-memory-validation.md).
Размеры локально собранных образов на этой машине: Spark — около 3,37 ГБ, Размеры локально собранных образов на этой машине: Spark — около 3,37 ГБ,
Jupyter — 3,72 ГБ, IDE — 4,90 ГБ. Jupyter включает слои Spark, IDE включает слои Jupyter — 3,72 ГБ, IDE — 4,90 ГБ. Jupyter включает слои Spark, IDE включает слои
@@ -107,6 +116,27 @@ docker compose exec ide python3 /opt/src/spark/cluster_smoke.py
### Trino ### Trino
- Web UI: `http://localhost:8090` - Web UI: `http://localhost:8090`
- Контейнер ограничен 2 ГиБ RAM (`mem_limit: 2g`). `memswap_limit: 2g`
отключает swap для него: одинаковое значение задает общий предел RAM + swap.
- В [`trino/jvm.config`](../trino/jvm.config) heap Java начинается с 512 МиБ
и может вырасти до 1 ГиБ (`-Xms512M`, `-Xmx1G`). Остальная память контейнера
оставлена для потоков, служебных структур JVM и буферов вне heap.
Эти ограничения относятся к Trino; у всего Compose-проекта общего лимита
памяти нет. Если контейнер достигнет жесткого предела, он может быть завершен
системой. Увеличение только heap без изменения бюджета контейнера уменьшает
запас для памяти вне heap. См. [лимиты Compose](https://docs.docker.com/reference/compose-file/services/#mem_limit)
и [настройку JVM Trino](https://trino.io/docs/current/installation/deployment.html#jvm-config).
После обновления этих файлов примени настройки из терминала хоста:
```bash
docker compose up -d --no-deps --force-recreate trino
docker compose ps -a trino
```
Дождись `healthy`. Эта операция пересоздает только Trino и применяет в том числе
изменения содержимого `jvm.config`; таблицы остаются в MinIO и PostgreSQL.
CLI внутри контейнера: CLI внутри контейнера:
@@ -240,6 +270,7 @@ JupyterLab остаётся запасным интерфейсом. Он ред
| `docker-compose.yml` | состав сервисов, порты, volumes, init-контейнеры | | `docker-compose.yml` | состав сервисов, порты, volumes, init-контейнеры |
| `spark/spark-defaults.conf` | Spark master, catalog `lakehouse`, `s3a`, Iceberg extensions | | `spark/spark-defaults.conf` | Spark master, catalog `lakehouse`, `s3a`, Iceberg extensions |
| `trino/catalog/lakehouse.properties` | каталог Trino `lakehouse`, JDBC и S3-доступ | | `trino/catalog/lakehouse.properties` | каталог Trino `lakehouse`, JDBC и S3-доступ |
| `trino/jvm.config` | JVM Trino: heap до 1 ГиБ внутри контейнера с лимитом 2 ГиБ |
| `spark/Dockerfile` | образ Spark с Iceberg, S3A и Python-зависимостями | | `spark/Dockerfile` | образ Spark с Iceberg, S3A и Python-зависимостями |
| `jupyter/Dockerfile` | образ JupyterLab на базе Spark | | `jupyter/Dockerfile` | образ JupyterLab на базе Spark |
| `ide/Dockerfile` | code-server и расширения на базе образа Jupyter | | `ide/Dockerfile` | code-server и расширения на базе образа Jupyter |
+107
View File
@@ -0,0 +1,107 @@
# Проверка лимита памяти Trino
Дата: 19 октября 2026 года. Это отчет о проверке; актуальная конфигурация
находится в `docker-compose.yml` и `trino/jvm.config`, требования для учащегося —
в `START_HERE.md`.
## Что проверяли
Trino 478 в контейнере с пределом 2 ГиБ RAM, без swap, с Java heap от 512 МиБ
до 1 ГиБ. JVM сама подбирает размер регионов G1; вместо настройки образа
`G1HeapRegionSize=32M` для большого heap получен регион 1 МиБ.
Среда: Linux x86_64, Docker Engine, cgroup v2, 6 CPU и 11,14 ГиБ памяти,
видимых Docker. Остальные сервисы стенда работали одновременно. Общего лимита
8 ГБ для проекта или виртуальной машины в этом прогоне не было.
Исходные файлы основного маршрута курса:
| Файл | Размер, байт |
| --- | ---: |
| `yellow_tripdata_2024-01.parquet` | 49 961 641 |
| `yellow_tripdata_2024-02.parquet` | 50 349 284 |
| `yellow_tripdata_2024-03.parquet` | 60 078 280 |
| `taxi_zone_lookup.csv` | 12 331 |
Файлы взяты из уже скачанного учебного набора, без выборки или сокращения.
## Сценарий
1. Перед изменением проверены отсутствие активных Spark-приложений и запросов
Trino, чтение существующей таблицы `lakehouse.default.spark_trino_smoke`.
2. Пересоздан только Trino. Запуск до `SERVER STARTED` занял около 25 секунд,
healthcheck прошел.
3. Созданы отдельная временная схема `trino_memory_<id>` и собственный префикс
`validation/trino_memory_<id>/raw/` в MinIO. Таблицы курса не перезаписывались.
4. Spark подготовил bronze и справочник по SQL Модуля 4; фильтры, нормализации,
два JOIN со справочником и silver выполнены кодом Модуля 5. Проверки качества
этого модуля также прошли. Получены 9 554 778 строк bronze, 9 418 184 строк
silver и 265 строк справочника.
5. Через Python-клиент Trino выполнены 11 запросов из Модуля 6: просмотр схем,
таблиц и колонок, выборки, подсчет строк, общие метрики, агрегаты по районам
и топ-10 зон. Имена таблиц заменены на временные; SQL сохранен.
6. Дополнительно дважды выполнен JOIN всей bronze со справочником зон и
группировкой по району:
```sql
SELECT z.Borough, count(*) AS trips, avg(b.fare_amount) AS avg_fare
FROM <bronze> b
LEFT JOIN <zones> z ON b.PULocationID = z.LocationID
GROUP BY z.Borough
ORDER BY trips DESC;
```
7. Подсчет строк, общие метрики, агрегаты по районам, топ зон, чтение созданной
Spark таблицы итогов и оба JOIN сверены с результатами Spark. Для чисел с
плавающей точкой использован допуск `1e-8`. Ошибки Python-клиента Trino
пробрасывались наружу, без обработчика исключений из ноутбука.
8. Повторно прочитана прежняя smoke-таблица: результат `1 / from_spark` сохранен.
Всего завершились успешно 14 запросов. Временные таблицы удалены с `PURGE`,
затем удалены временная схема и собственный raw-префикс. После `PURGE`
отдельно удалены восемь пустых маркеров каталогов в собственном warehouse-префиксе.
Проверено отсутствие временных объектов; исходные Parquet/CSV на хосте сохранены.
## Измерения
| Показатель | Результат |
| --- | ---: |
| Лимит контейнера (`memory.max`) | 2 147 483 648 байт |
| Лимит swap (`memory.swap.max`) | 0 |
| Фактический `MaxHeapSize` через `jcmd 1 VM.flags` | 1 073 741 824 байта |
| Пик контейнера Trino (`memory.peak`) | 1 340 874 752 байта, около 1,25 ГиБ |
| События `oom`, `oom_kill`, `max` в `memory.events` | 0 |
| Перезапуски Trino | 0 |
| Пик суммы `memory.current` восьми контейнеров | около 5,89 ГиБ |
| Пик той же суммы за вычетом `inactive_file` | около 5,44 ГиБ |
Суммарная память снималась раз в секунду, получено 165 отсчетов во время
подготовки таблиц, запросов и очистки. Пик Trino взят из счетчика cgroup,
который учитывает и запуск контейнера. Вычитание `inactive_file` приближает
сумму к показателю памяти в `docker stats`; файловый кэш показан отдельно.
Агрегаты по silver обработали 9 418 184 строки каждый, что подтверждено
статистикой запросов Trino. `count(*)` по bronze использовал метаданные Iceberg;
проверкой чтения bronze служил также JOIN со справочником.
## Границы вывода
Бюджет Trino 2 ГиБ / heap 1 ГиБ достаточен для проверенных запросов на основном
наборе курса при одном учащемся. Измерение не подтверждает работу всех восьми
модулей под общим жестким лимитом 8 ГБ. В сумму контейнеров не входят Docker
daemon, ядро и другие процессы Linux/WSL2. Docker Desktop, Windows, ARM64,
параллельные занятия и расширенный набор Taxi за 12 месяцев не проверялись.
Для повторной проверки подними стенд с этой конфигурацией и пройди модули 3–6
на трех месяцах Taxi, добавив JOIN выше. Временная схема нужна, если важно
сохранить существующие учебные таблицы. Примененный лимит можно проверить
с хоста:
```bash
docker inspect --format '{{.HostConfig.Memory}} {{.HostConfig.MemorySwap}}' trino
docker compose exec trino jcmd 1 VM.flags
docker compose exec trino cat /sys/fs/cgroup/memory.peak
docker compose exec trino cat /sys/fs/cgroup/memory.events
```
Последние два пути относятся к cgroup v2; счетчики накапливаются с запуска
контейнера. Числа нового прогона могут отличаться.
+17
View File
@@ -0,0 +1,17 @@
# Параметры образа trinodb/trino:478 с бюджетом памяти для локального курса.
-server
-agentpath:/usr/lib/trino/bin/libjvmkill.so
-Xms512M
-Xmx1G
# Размер регионов G1 выбирает JVM с учетом небольшого heap.
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-XX:ReservedCodeCacheSize=256M
-XX:PerMethodRecompilationCutoff=10000
-XX:PerBytecodeRecompilationCutoff=10000
-Djdk.attach.allowAttachSelf=true
-Djdk.nio.maxCachedBufferSize=2000000
-Dfile.encoding=UTF-8
-XX:+EnableDynamicAgentLoading