fix(trino): bound memory for the learning stack
This commit is contained in:
1 parent
21f3570b89
commit
863d658a5f
6 files changed
+177
-11
No files matched your search
@@ -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
@@ -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 не отвечает или конфигурация не читается,
|
||||
исправь эту ошибку до сборки.
|
||||
|
||||
|
||||
@@ -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
@@ -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 |
|
||||
|
||||
@@ -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; счетчики накапливаются с запуска
|
||||
контейнера. Числа нового прогона могут отличаться.
|
||||
@@ -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
|
||||
Reference in new issue
Block a user