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 и
10 ГБ памяти, доступных Docker, а также от 20 ГБ свободного места перед сборкой.
ориентировочно 8 ГБ памяти для Docker, а также от 20 ГБ свободного места перед сборкой.
Trino ограничен 2 ГиБ памяти контейнера и 1 ГиБ Java heap.
Подробности и границы проверки — в [системных требованиях](./START_HERE.md#системные-требования).
Краткий запуск из корня репозитория после подготовки по `START_HERE`:
+13 -7
View File
@@ -39,15 +39,21 @@
| Ресурс | Рекомендация | Что проверить |
| --- | --- | --- |
| Процессор | Не менее 4 CPU, доступных Docker | В Docker Desktop/WSL2 может стоять меньший лимит |
| Память Docker | Не менее 10 ГБ RAM | Это память для контейнеров, а не общий объем памяти компьютера |
| Память Docker | Ориентир — 8 ГБ RAM; 10 ГБ дают дополнительный запас | Это память для среды Docker, а не общий объем памяти компьютера |
| Память компьютера | 16 ГБ RAM или больше | Оставь память ОС, браузеру и другим приложениям |
| Свободное место | Не менее 20 ГБ перед первой сборкой; 30 ГБ с запасом | На диске Docker и в папке репозитория: образы, кэш сборки, исходные данные и таблицы |
Это рекомендуемый бюджет, а не измеренный минимальный порог. Полный курс на
машине с 8 ГБ RAM не проверен. В Docker Desktop проверь
[лимиты ресурсов](https://docs.docker.com/desktop/settings-and-maintenance/settings/#resources);
для режима WSL2 лимиты задаются у виртуальной машины WSL2. Место внутри диска
Docker и свободное место на диске компьютера — отдельные ограничения.
Это рекомендуемый бюджет для одного активного ноутбука, а не измеренный минимум.
На Windows с WSL2 по умолчанию доступно 50% RAM компьютера: при 16 ГБ это 8 ГБ
для всей WSL2, включая Docker. Лимит можно настроить, это не аппаратное
ограничение. См. [настройки WSL2](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#main-wsl-settings)
и [ресурсы 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 ГБ относительно
Jupyter; базовые слои у них общие. MinIO скачивается готовым, компилировать его
@@ -74,7 +80,7 @@ docker compose config --quiet
В `docker version` должны быть разделы Client и Server, версия Compose — не
ниже 2.17. `docker info` показывает ресурсы, которые видит Docker; память дана
в байтах (10 ГБ — примерно 10 000 000 000 байт). Последняя команда при успехе
в байтах (8 ГиБ — 8 589 934 592 байта). Последняя команда при успехе
ничего не печатает. Если Docker не отвечает или конфигурация не читается,
исправь эту ошибку до сборки.
+4
View File
@@ -231,6 +231,9 @@ services:
image: trinodb/trino:478
container_name: trino
hostname: trino
# Heap JVM ограничен отдельно в trino/jvm.config; остальное — запас вне heap.
mem_limit: 2g
memswap_limit: 2g
networks:
- spark-net
depends_on:
@@ -245,6 +248,7 @@ services:
- "8090:8080" # Web UI Trino
volumes:
- ./trino/catalog:/etc/trino/catalog:ro
- ./trino/jvm.config:/etc/trino/jvm.config:ro
networks:
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 и около
11,1 ГиБ памяти, видимых Docker. Выполнены первый ноутбук в Chromium и проверка
Spark → Iceberg → Trino. Прогона всех восьми модулей с измерением пиков памяти
и диска не было; минимальный объем RAM не установлен. Docker Desktop и ARM64
в этой проверке не запускались.
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 в этой проверке не запускались.
Методика и результаты сохранены в [отчете проверки](../plans/trino-memory-validation.md).
Размеры локально собранных образов на этой машине: Spark — около 3,37 ГБ,
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
- 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 внутри контейнера:
@@ -240,6 +270,7 @@ JupyterLab остаётся запасным интерфейсом. Он ред
| `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 |
+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