JMX, OpenMetrics/Prometheus и OpenTelemetry-трейсинг
Web UI и EXPLAIN ANALYZE отвечают на вопрос «что не так с этим запросом». Но эксплуатация кластера требует другого: непрерывно знать, что происходит со всем кластером во времени — растёт ли очередь, не упирается ли heap в потолок, не деградировал ли GC, какой воркер отстаёт. Web UI хранит данные в памяти координатора недолго и показывает только «сейчас». Для исторических графиков, алертов и SLA нужна машинная наблюдаемость.
У Trino её три слоя: JMX — внутренний реестр метрик JVM-процесса; OpenMetrics — HTTP-эндпойнт, с которого Prometheus снимает эти метрики по расписанию; OpenTelemetry — распределённый трейсинг отдельных запросов. Этот урок разбирает все три и показывает, как собрать из них рабочий мониторинг.
JMX: реестр метрик внутри JVM
Trino написан на Java и работает как JVM-процесс. JVM предоставляет стандартный механизм самонаблюдения — JMX (Java Management Extensions). Любой компонент регистрирует MBean — объект с именованными атрибутами-метриками. JVM публикует свои MBean’ы (heap, garbage collector, потоки, классы), и Trino поверх регистрирует сотни своих: статистику пула памяти, очереди запросов, исполнителей задач, каждого коннектора.
У каждого MBean есть имя вида java.lang:type=Memory или trino.execution:name=QueryManager. Метрики JMX — это пульс кластера на уровне процесса: сколько запросов выполняется и стоит в очереди, какой heap занят, сколько времени съел последний цикл GC, сколько задач активно на воркере.
Ключевой удобный приём: Trino отдаёт собственные JMX-метрики через коннектор jmx. Включается одним каталогом:
# etc/catalog/jmx.properties
connector.name=jmx
После этого MBean’ы становятся обычными таблицами, и метрики можно запрашивать на SQL:
-- Текущее состояние памяти JVM координатора
SELECT node, heapmemoryusage_used, heapmemoryusage_max
FROM jmx.current."java.lang:type=memory";
-- Сводка по менеджеру запросов
SELECT runningqueries, queuedqueries, startedqueries
FROM jmx.current."trino.execution:name=querymanager";
Схема jmx.current — мгновенный снимок. Trino умеет ещё периодически дампить выбранные MBean’ы в схему jmx.history — это историческая таблица, доступная в SQL без внешней системы.
OpenMetrics: эндпойнт для Prometheus
JMX-таблицы хороши для разовой диагностики, но Prometheus — стандарт де-факто для исторического мониторинга — не умеет читать JMX напрямую. Поэтому Trino отдаёт те же метрики ещё и через HTTP в формате OpenMetrics (расширение Prometheus exposition format). Эндпойнт встроен в координатор и воркеры; по умолчанию это путь /metrics на том же HTTP-порту.
Prometheus периодически делает scrape — HTTP-запрос к /metrics — и сохраняет ответ как временные ряды. Конфигурация на стороне Prometheus:
# prometheus.yml
scrape_configs:
- job_name: trino-coordinator
metrics_path: /metrics
scheme: https
static_configs:
- targets: ['coordinator:8443']
authorization:
type: Bearer
credentials: '<jwt-token>'
- job_name: trino-workers
metrics_path: /metrics
static_configs:
- targets: ['worker-1:8080', 'worker-2:8080']
Эндпойнт /metrics относится к защищённым ресурсам Trino: если на кластере включена аутентификация, scrape тоже должен аутентифицироваться (на схеме выше — Bearer-токен). Это часть продакшен-настройки, а не опциональная деталь.
Метрики, которые в реальном мониторинге Trino выносят на дашборд в первую очередь:
| Группа метрик | За чем следит | Тревожный сигнал |
|---|---|---|
| Running / queued queries | Нагрузка и насыщение кластера | Очередь устойчиво растёт |
| Heap used / max | Давление на память | used стабильно выше 80-85% от max |
| GC pause time / count | Здоровье сборщика мусора | Длинные или частые паузы |
| Failed queries rate | Доля падающих запросов | Скачок относительно фона |
| Cluster memory pool | Сколько распределённой памяти занято | Близко к лимиту, риск OOM-killer |
| Worker count | Воркеры в кластере | Просадка числа воркеров |
| Blocked / running drivers | Пропускная способность исполнения | Много blocked при простое CPU |
Поверх Prometheus ставят Grafana. У Trino есть и официальный Grafana Trino Data Source Plugin — он позволяет Grafana выполнять SQL-запросы прямо к Trino (например, строить бизнес-панели по данным lakehouse). Не путайте: Prometheus собирает операционные метрики кластера, а Grafana-плагин запускает аналитические запросы к данным.
ClickHouse: мониторинг через system.* таблицы и метрики Это разные задачи.
Стоит понять, почему Prometheus устроен как pull-модель — он сам ходит за метриками, а не Trino их отправляет. У pull-модели есть конкретные эксплуатационные плюсы. Prometheus всегда знает, отвечает ли цель: если scrape не прошёл, это само по себе сигнал — нода недоступна. Цели описаны централизованно в конфигурации Prometheus, и добавить новый воркер в мониторинг — это правка одного файла, а не перенастройка каждой ноды. И нагрузка на цель предсказуема: scrape происходит по расписанию с известным интервалом, а не лавиной при всплеске активности. Trino остаётся пассивным: он лишь держит эндпойнт /metrics готовым, а инициатива — за Prometheus. Эта же модель объясняет, почему интервал scrape — это компромисс: слишком частый создаёт лишнюю нагрузку, слишком редкий пропускает короткие всплески; типично его ставят в районе нескольких десятков секунд.
Минимальный полезный набор алертов для продакшен-Trino: устойчиво растущая очередь запросов; heap воркеров выше 85% дольше нескольких минут; всплеск длительности GC-пауз; падение числа живых воркеров; рост доли failed queries. Эти пять покрывают подавляющее большинство инцидентов до того, как их заметят пользователи.
Как ориентироваться в MBean’ах
JMX-метрик у Trino сотни, и без понимания их именования в них легко утонуть. Имя MBean устроено как домен:свойства и группирует метрики по происхождению.
Домен java.lang — это метрики самой JVM, общие для любого Java-процесса: java.lang:type=Memory (heap и non-heap), java.lang:type=GarbageCollector,name=G1* (циклы сборщика мусора), java.lang:type=Threading (потоки). Эти MBean’ы отвечают на вопрос о здоровье JVM-процесса как такового.
Домены, начинающиеся с trino., — это уже метрики самого движка. trino.execution:name=QueryManager — менеджер запросов: сколько запросов запущено, выполняется, в очереди, упало. trino.memory:* — состояние пула памяти кластера. trino.execution.executor:* — исполнитель задач на воркере. У коннекторов есть свои MBean’ы со статистикой обращений к источникам.
Практический приём при незнакомой задаче — сначала посмотреть, что вообще есть: SHOW TABLES FROM jmx.current выведет все доступные MBean’ы как имена таблиц, и по имени домена легко понять, JVM это или движок, и про какую подсистему. Дальше — DESCRIBE нужной таблицы покажет её колонки-метрики.
Отдельно полезна схема jmx.history. jmx.current — это снимок «прямо сейчас», но Trino можно настроить периодически дампить выбранные MBean’ы в jmx.history, и тогда историческая динамика метрики становится доступна прямым SQL-запросом — без Prometheus. Это не замена полноценному мониторингу (история живёт в памяти координатора и теряется при рестарте), но для быстрого «как менялся heap за последний час» удобно: обычный SELECT с ORDER BY по времени.
OpenTelemetry: трейсинг отдельного запроса
Метрики агрегированы: они говорят «на кластере 40 запросов и heap на 70%», но не говорят, где конкретный медленный запрос потратил своё время. На этот вопрос отвечает распределённый трейсинг.
Trino инструментирован через OpenTelemetry — отраслевой стандарт трейсинга. Исполнение запроса представляется как trace — дерево span’ов. Span — это интервал с именем, временем начала и конца и атрибутами. Корневой span — весь запрос; дочерние — фазы планирования, стадии, задачи, обращения к коннекторам. Trino экспортирует трейсы по протоколу OTLP в любой совместимый бэкенд (Jaeger, Grafana Tempo, коммерческие APM).
Включается в конфигурации сервера:
# etc/config.properties
tracing.enabled=true
tracing.exporter.endpoint=http://otel-collector:4317
Где трейсинг даёт то, чего не дают метрики и EXPLAIN ANALYZE:
- Граница движка и источника. Span обращения к коннектору показывает, сколько запрос ждал именно внешнюю систему. Если федеративный запрос медленный из-за тормозящего PostgreSQL — на трейсе это отдельный длинный span, по агрегированным метрикам этого не видно.
- Сквозная картина через сервисы. Когда перед Trino стоит Trino Gateway или приложение со своей трассировкой, единый trace показывает путь запроса через всю систему: приложение, шлюз, координатор, воркеры.
- Латентность фаз планирования. Парсинг, анализ, оптимизация — отдельные span’ы. Если запрос с гигантским IN-списком долго планируется, трейс это покажет, а
EXPLAIN ANALYZE(он меряет исполнение) — нет.
Какой инструмент когда
Три слоя не конкурируют, а закрывают разные вопросы. Их полезно держать в голове как лестницу диагностики.
| Вопрос | Инструмент |
|---|---|
| Что прямо сейчас на кластере? | Web UI |
| Как нагрузка и здоровье менялись за сутки/неделю? | Prometheus + Grafana (через OpenMetrics) |
| Разовый замер конкретного MBean? | jmx-коннектор, SQL |
| Почему медленный конкретный запрос внутри Trino? | EXPLAIN ANALYZE |
| Где запрос потратил время через сервисы и коннекторы? | OpenTelemetry-трейс |
JMX, Prometheus и OpenTelemetry — это машинная наблюдаемость: непрерывная, агрегированная, с алертами. Web UI и EXPLAIN ANALYZE — человеческая: точечная, по запросу. Зрелая эксплуатация Trino использует оба класса. Метрики Prometheus говорят, что проблема есть и когда она началась; трейсы и EXPLAIN ANALYZE говорят, в чём именно она. Алертинг без точечных инструментов оставляет вас с фактом «плохо» без причины; точечные инструменты без метрик означают, что вы узнаёте о проблемах от пользователей.
Попробуй сам
Включите на локальном Trino jmx-коннектор и поработайте с метриками через SQL.
- Добавьте каталог
etc/catalog/jmx.propertiesсо строкойconnector.name=jmxи перезапустите контейнер. - Посмотрите доступные MBean’ы как таблицы:
SHOW TABLES FROM jmx.current;
- Снимите состояние памяти и менеджера запросов:
SELECT node, heapmemoryusage_used, heapmemoryusage_max
FROM jmx.current."java.lang:type=memory";
SELECT node, runningqueries, queuedqueries, failedqueries
FROM jmx.current."trino.execution:name=querymanager";
- Откройте в браузере эндпойнт
http://localhost:8080/metricsи найдите в текстовом выводе строки про память и число запросов — это ровно то, что снимал бы Prometheus. - Сопоставьте: какие из метрик из таблицы тревожных сигналов выше вы видите и в JMX-таблицах, и в выводе
/metrics?
Цель — увидеть, что JMX и OpenMetrics — это два представления одного набора метрик, и что мониторинг Trino не требует ничего, кроме включения уже встроенных механизмов.