Конфигурационные файлы: config, node, jvm, log.properties
Trino-нода — это JVM-процесс, поведение которого целиком задаётся набором файлов в каталоге etc. Никакой «панели управления» нет: разворачивание Trino — это написать правильные файлы в etc и запустить процесс. Поэтому, прежде чем говорить о тюнинге, безопасности и Kubernetes, надо разобрать сам фундамент — какие файлы есть и за что каждый отвечает.
Базовых файлов четыре: config.properties, node.properties, jvm.config, log.properties. Плюс отдельные файлы каталогов в etc/catalog/. Этот урок разбирает каждый из четырёх: что в нём, какие свойства критичны и чем настройки координатора отличаются от настроек воркера.
Каталог etc: карта конфигурации
Вся конфигурация ноды Trino живёт в одном каталоге, обычно etc. Структура:
Каждая нода — координатор и каждый воркер — имеет свой набор этих файлов. Часть свойств на всех нодах одинакова, часть отличается. Разберём файлы по одному.
config.properties: конфигурация сервера
etc/config.properties — главный файл. Он определяет, что нода делает в кластере.
Минимальный config.properties для координатора:
# etc/config.properties — КООРДИНАТОР
coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8080
discovery.uri=http://trino-coordinator:8080
query.max-memory=20GB
query.max-memory-per-node=30%
Минимальный config.properties для воркера:
# etc/config.properties — ВОРКЕР
coordinator=false
http-server.http.port=8080
discovery.uri=http://trino-coordinator:8080
query.max-memory=20GB
query.max-memory-per-node=30%
Ключевые свойства:
coordinator—trueилиfalse. Главное различие между ролями: одна нода в кластере имеетcoordinator=true, все остальные —coordinator=false. Координатор парсит запросы, планирует и управляет воркерами; воркеры исполняют задачи и обрабатывают данные.node-scheduler.include-coordinator— разрешить ли планировщику давать координатору обрабатывать данные как воркеру. Обычноfalse: на продакшен-кластере координатор занят координацией и не должен конкурировать за ресурсы с обработкой данных.trueставят на крошечных установках (один-два узла) или в учебных целях.http-server.http.port— порт HTTP-сервера, обычно8080. Клиенты, Web UI и межнодовая коммуникация идут через него.discovery.uri— URI discovery service. Discovery встроен в координатор, поэтому это всегда адрес координатора. Воркеры по этому URI регистрируются в кластере; на самом координаторе это указатель на себя.
discovery.uri должен указывать на координатор и быть одинаковым на всех нодах кластера. Это самая частая ошибка при ручном развёртывании: воркер с неверным discovery.uri просто не появится в кластере — координатор о нём не узнает, и его мощность не будет использоваться. Если воркер «не виден», первым делом проверяют именно discovery.uri.
node.properties: идентичность ноды
etc/node.properties описывает, кто эта нода в своём окружении.
# etc/node.properties
node.environment=production
node.id=trino-worker-a3f9c1e8
node.data-dir=/var/trino/data
Три свойства, и у каждого своё правило:
node.environment— имя окружения. Должно быть одинаковым на всех нодах одного кластера: координатор и воркеры с разнымnode.environmentне образуют единый кластер. Это механизм, не дающий случайно смешать ноды разных кластеров — например, production и staging.node.id— уникальный идентификатор ноды. Должен быть уникальным для каждой ноды и, что важно, стабильным между перезапусками одной и той же ноды. Поnode.idTrino опознаёт ноду; если он скачет, кластер видит «новую» ноду на каждый рестарт.node.data-dir— каталог для данных ноды: логи, локальное состояние.
| Свойство | Правило | Зачем |
|---|---|---|
node.environment | одинаков на всех нодах кластера | не дать смешать разные кластеры |
node.id | уникален для ноды, стабилен между рестартами | опознавать ноду между перезапусками |
node.data-dir | путь к данным ноды | где нода хранит логи и состояние |
Правила node.id и node.environment особенно важны на Kubernetes, где поды эфемерны. Helm chart Trino решает это так: одинаковый node.environment для всего деплоймента, а уникальность node.id обеспечивается на уровне пода — иначе при пересоздании пода кластер видел бы каждый раз новый узел. Подробнее об этом — в уроке про Kubernetes.
jvm.config: опции виртуальной машины
etc/jvm.config — список опций командной строки JVM, по одной на строку. Это не properties-формат ключ=значение, а именно набор флагов, как если бы их передали java напрямую.
Пример jvm.config:
-Xmx64G
-XX:InitialRAMPercentage=80
-XX:MaxRAMPercentage=80
-XX:+ExitOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Djdk.attach.allowAttachSelf=true
Что задаётся здесь:
-Xmx— максимальный размер JVM heap. Главная цифра тюнинга: от неё, как мы видели в модуле про память, считаются дефолтыquery.max-memory-per-nodeиmemory.heap-headroom-per-node.- Настройки garbage collector — GC и его параметры.
- Флаги
-XX— поведение JVM: дамп heap при OOM, выход процесса при OOM и прочее.
Глубоко тюнинг JVM — heap, GC, headroom для координатора и воркера — разбирается в следующем уроке; здесь важно запомнить лишь формат: jvm.config — это флаги по строке, не пары ключ=значение.
Каталог временных файлов, который использует JVM, не должен быть смонтирован с флагом noexec. Trino и его зависимости могут распаковывать в temp-каталог нативный код и исполнять его; при noexec запуск завершится непонятной ошибкой. Это типичная засада в зарегулированных окружениях, где /tmp намеренно монтируют с noexec.
log.properties: уровни логирования
etc/log.properties задаёт уровни логирования — насколько подробно Trino пишет в лог, по пакетам Java.
# etc/log.properties
# Общий уровень
io.trino=INFO
# Подробнее для конкретного пакета — например, при отладке коннектора
io.trino.plugin.iceberg=DEBUG
Формат — пакет=уровень. Уровни: DEBUG, INFO, WARN, ERROR. Указанный уровень и всё, что серьёзнее него, попадает в лог; всё, что менее серьёзно, отбрасывается. INFO — разумный дефолт. DEBUG включают точечно, на конкретный пакет, при отладке проблемы — глобальный DEBUG зальёт лог и сам станет источником нагрузки.
Что одинаково на всех нодах, а что отличается
Соберём картину. Разворачивая кластер, держи в голове, какие свойства разные на координаторе и воркере, а какие должны совпадать:
| Файл / свойство | Координатор | Воркер | Правило |
|---|---|---|---|
config.properties coordinator | true | false | различается — определяет роль |
config.properties discovery.uri | адрес координатора | адрес координатора | одинаков на всех нодах |
node.properties node.environment | одно значение | то же значение | одинаков на всех нодах |
node.properties node.id | уникален | уникален | различается — уникален у каждой ноды |
jvm.config -Xmx | по роли | по роли | может различаться координатор/воркер |
etc/catalog/*.properties | те же каталоги | те же каталоги | одинаковы на всех нодах |
Главное: coordinator и node.id различаются; discovery.uri, node.environment и набор каталогов — одинаковы. Перепутать здесь — типичная причина «кластер не собрался»: воркеры не видны или не образуют единый кластер.
Попробуй сам
Разверни Trino-кластер вручную из конфигурационных файлов — без готового образа «всё включено».
- Подготовь два набора каталога
etc— для координатора и для воркера. Для координатора:config.propertiesсcoordinator=true,node-scheduler.include-coordinator=false; для воркера —coordinator=false. На обоих — одинаковыйdiscovery.uri(адрес координатора) и одинаковыйnode.environment, но разныеnode.id. - Запусти координатор и воркер (двумя контейнерами или процессами). Открой Web UI координатора и проверь во вкладке кластера: воркер появился, число активных воркеров — 1.
- Намеренно сломай конфигурацию воркера: поставь неверный
discovery.uriили другойnode.environment, перезапусти воркер. Убедись, что он пропал из кластера, и посмотри, что говорит лог. - В
log.propertiesворкера включиDEBUGдля одного пакета (например,io.trino.plugin.tpch) и понаблюдай, как изменилась подробность лога.
Цель — прочувствовать, что кластер Trino собирается именно из правильных файлов etc, и научиться отлаживать «невидимый воркер».