Learning Platform
Глоссарий Troubleshooting
Урок 16.01 · 22 мин
Средний
web-uiobservabilityquery-detailslive-plan

Web UI: список запросов, стадии и live-план

Когда запрос на Trino выполняется медленно, у вас есть три уровня инструментов диагностики. Самый глубокий — EXPLAIN ANALYZE VERBOSE и JMX-метрики. Самый поверхностный, но почти всегда первый — встроенный Web UI координатора. Он не требует ни настройки, ни сторонних систем: координатор отдаёт его на том же HTTP-порту, что и protocol API (по умолчанию 8080). Открываете http://coordinator:8080, и сразу видите, что происходит на кластере прямо сейчас.

Web UI — это окно в живую модель исполнения Trino. Всё, что вы изучали в предыдущих модулях — query, stages, tasks, splits, drivers, operators — здесь становится не абстракцией из документации, а кликабельным деревом с цифрами. Этот урок учит читать Web UI так, чтобы за 30 секунд понять, на какой стадии запрос «застрял» и почему.


Что показывает главная страница

Главная страница Web UI — это список запросов. Координатор хранит метаданные о завершённых запросах в памяти ограниченное время (по умолчанию информация о последних запросах доступна, пока не вытеснится новыми), поэтому UI — инструмент оперативной диагностики, а не исторического анализа. Для истории нужны event listeners, о которых речь в уроке 4.

В верхней части — сводка по кластеру: число активных воркеров, суммарная нагрузка (running queries, queued queries), пропускная способность в строках и байтах в секунду. Ниже — собственно список, каждая строка которого описывает один запрос.

Анатомия строки запроса в списке Web UI
Query IDИдентификатор вида 20260511_103245_00042_a7x9k: дата, время, порядковый номер, случайный суффикс кластера. По нему запрос ищется в логах и через protocol API.
StateRUNNING, QUEUED, FINISHED, FAILED, USER_CANCELLED. QUEUED означает, что запрос ждёт в resource group и ещё не начал исполнение.
ПрогрессДоля завершённых splits ко всем известным splits. Показатель неточный: число splits меняется в рантайме по мере lazy-генерации источником.
РесурсыСуммарное CPU-время по всем задачам и пиковая распределённая память запроса. Главные числа для оценки стоимости.

Список можно фильтровать и сортировать. Самые полезные сортировки на практике — по CPU Time (находит запросы, которые жгут процессор кластера) и по Cumulative Memory (находит запросы-обжоры по памяти). Поле State позволяет мгновенно отделить QUEUED от RUNNING: если запрос долго висит в QUEUED, проблема не в плане и не в данных, а в resource group — кластер просто не дал запросу слот.

TIP

Перед тем как открывать страницу деталей и копаться в стадиях, посмотрите на State в списке. Очень частая ошибка диагностики — оптимизировать SQL запроса, который на самом деле просто стоит в очереди resource group. Эти два класса проблем лечатся совершенно по-разному.


Страница деталей запроса

Клик по Query ID открывает страницу деталей — главный диагностический экран Trino. Она разделена на несколько блоков.

Overview — сводка: текст SQL, пользователь, resource group, источник (CLI, JDBC, dbt), тайминги. Здесь же — Session-параметры, с которыми запрос был запущен: это критично, потому что неожиданное поведение часто объясняется случайно выставленным session property.

Resource Utilization и Timeline — графики потребления CPU и памяти во времени. По форме графика видно характер запроса: ровное плато CPU — равномерная нагрузка; пила — чередование стадий; резкий пик памяти в конце — финальная агрегация или сортировка собирает всё в одном месте.

Stages — дерево стадий распределённого плана. Это ядро страницы, разберём его отдельно ниже.

Tasks — таблица всех задач с разбивкой по воркерам. Здесь ищут перекос (skew): если одна задача обработала на порядок больше строк или потратила больше CPU, чем соседи по стадии, — это data skew, и именно он часто делает запрос медленным.

Внизу страницы — счётчики операторов и, отдельной кнопкой, JSON-представление запроса целиком. JSON — это полный дамп всего, что координатор знает о запросе; в нём лежат данные, которых нет в визуальном UI, и его удобно прикладывать к багрепортам.


Дерево стадий: где «застрял» запрос

Блок Stages показывает распределённый план как дерево. Напомним таксономию: stage — концептуальная фаза плана, она не исполняется сама; её исполняют tasks на воркерах. В Web UI каждая стадия — это карточка с агрегированными по её задачам числами.

Нумерация стадий идёт сверху вниз от корня: Stage 0 — корневая (финальный вывод клиенту), стадии с большими номерами — ближе к источникам данных. Данные текут снизу вверх: source-стадии читают из коннекторов, промежуточные обменивают данные через exchange, корневая отдаёт результат.

Дерево стадий запроса с join двух таблиц
Stage 0 — SINGLEКорневая стадия. Исполняется одной задачей на одном воркере. Собирает финальный результат и отдаёт его клиенту через protocol API.
exchange (gather)
Stage 1 — HASHСтадия с join-оператором. Партиционирована по hash от join-ключа: каждая задача отвечает за свой диапазон значений ключа.
repartition по join-ключу
Stage 2 — SOURCESource-стадия probe-стороны. Задачи исполняются там, где доступны splits большой fact-таблицы. Читает данные через коннектор.
Stage 3 — SOURCESource-стадия build-стороны. Читает dimension-таблицу, строит hash-таблицу для join.

Каждая карточка стадии показывает: число задач, число splits (завершённых и всего), сколько строк прошло на вход и выход, потраченное CPU-время, объём данных в обменах (buffered/queued). Чтобы найти узкое место, смотрят на стадию, которая накопила больше всего CPU-времени или wall-time относительно других. Это и есть «горячая» стадия — оптимизировать имеет смысл именно её.

Полезные сигналы прямо в дереве:

  • Перекос между задачами одной стадии. Карточка стадии показывает min/avg/max по задачам. Большой разрыв max от avg — data skew.
  • Buffered data растёт, а CPU простаивает. Стадия-потребитель не успевает за продьюсером или, наоборот, заблокирована — backpressure через exchange-буферы.
  • Source-стадия с огромным input rows и маленьким output rows. Читается много, а фильтр отсекает почти всё. Сигнал, что не сработал pushdown или dynamic filtering — данные читаются с диска зря.
Что видно в дереве стадийВероятная причинаКуда копать дальше
Одна стадия копит почти всё CPUТяжёлая операция (join, aggregation)EXPLAIN ANALYZE этой стадии, урок 2
max строк на задачу намного больше avgData skew по ключу партиционированияКлюч join/group by, урок 5
Source-стадия читает все строки таблицыНе сработал predicate pushdown / dynamic filteringПлан запроса, модуль 8
Стадия RUNNING, но CPU около нуляBackpressure или ожидание splitsExchange-буферы, scheduler

Tasks: как находят перекос

Отдельно стоит блока Tasks — таблица всех задач запроса. Стадия в Trino распараллеливается на множество задач, каждая на своём воркере, и каждая обрабатывает свой набор сплитов. В идеале задачи одной стадии нагружены одинаково: стадия закончится, когда закончит последняя задача, поэтому равномерность — это и есть скорость стадии.

Перекос (data skew) ломает эту равномерность. Если значения ключа партиционирования распределены неравномерно — например, одно значение customer_id встречается в разы чаще остальных, или ключ содержит много NULL, — то задача, которой достался «тяжёлый» диапазон ключа, обработает кратно больше строк, чем соседи. Остальные задачи давно закончили и простаивают, а стадия всё ещё ждёт одну перегруженную.

В таблице Tasks это видно прямо: задачи отсортированы, и колонки строк, CPU-времени, памяти показывают разброс. Если у одной задачи эти числа на порядок выше, чем у медианной по той же стадии, — это перекос. Web UI не скажет, по какому ключу он возник, но точно укажет, что он есть и в какой стадии. Дальше причину ищут в SQL: какой ключ join или GROUP BY соответствует горячей стадии, нет ли в нём доминирующего значения или NULL.

Перекос коварен тем, что добавление воркеров его не лечит: новые воркеры получат лёгкие задачи и быстро освободятся, а одна тяжёлая задача как была, так и останется на одном воркере. Лечится перекос на уровне данных и запроса — пересмотром ключа, отдельной обработкой доминирующего значения, фильтрацией NULL, — а не масштабированием кластера. Поэтому распознать перекос по блоку Tasks важно: он отправляет диагностику по верному пути.


Live-план: исполнение в реальном времени

У страницы деталей запущенного запроса есть вкладка Live Plan. Она рисует план запроса как граф и в реальном времени подсвечивает прогресс: сколько строк уже прошло через каждый оператор, какие операторы активны, где данные «копятся». Это та же информация, что в дереве стадий, но визуализированная как граф операторов и обновляемая на лету.

Live-план особенно полезен для длинных запросов: вы запускаете тяжёлый аналитический запрос, открываете Live Plan и буквально наблюдаете, как данные текут по плану. Видно, на каком операторе фронт исполнения остановился. Если граф несколько секунд «стоит» на конкретном join — вы нашли узкое место, не дожидаясь конца запроса.

После завершения запроса для него доступен Stage Performance — статический срез того же графа с финальными числами. Live Plan отвечает на вопрос «что происходит прямо сейчас», Stage Performance — «что произошло».

NOTE

Web UI отвечает на вопросы «где» и «сколько»: какая стадия горячая, сколько строк и CPU она съела, есть ли перекос. Но он не отвечает на вопрос «почему» план именно такой. За «почему» отвечает EXPLAIN — он показывает решения оптимизатора. Поэтому рабочая связка такая: Web UI локализует проблемную стадию, EXPLAIN ANALYZE объясняет её. Этому посвящён следующий урок.

Стоит помнить про ограничения. Web UI живёт на координаторе и хранит данные в его памяти ограниченное время — это инструмент «здесь и сейчас», не система мониторинга. В продакшене UI обычно закрывают аутентификацией: он показывает тексты SQL, имена пользователей, схему данных — чувствительную информацию. Доступ к UI стоит выдавать так же осторожно, как доступ к самому Trino.


Попробуй сам

Поднимите Trino локально (одного контейнера достаточно) и откройте Web UI на http://localhost:8080.

  1. Запустите заведомо тяжёлый запрос на встроенном коннекторе:
SELECT
  l.returnflag,
  count(*) AS cnt,
  sum(l.extendedprice) AS revenue
FROM tpch.sf10.lineitem l
JOIN tpch.sf10.orders o ON l.orderkey = o.orderkey
WHERE o.orderdate >= DATE '1995-01-01'
GROUP BY l.returnflag
ORDER BY revenue DESC;
  1. Пока он выполняется, найдите его в списке запросов, откройте страницу деталей и переключитесь на Live Plan. Понаблюдайте, через какой оператор данные текут дольше всего.
  2. Откройте блок Stages. Найдите стадию, которая накопила больше всего CPU-времени. Это source-стадия скана lineitem или стадия с join?
  3. Откройте вкладку Tasks. Сравните min/avg/max строк по задачам внутри одной стадии — есть ли перекос?
  4. В правом верхнем углу страницы деталей найдите ссылку на JSON-представление запроса. Откройте его и найдите в нём поле с пиковой памятью запроса.

Цель — научиться за минуту локализовать «горячую» стадию, не открывая ни EXPLAIN, ни логи.


Проверка знанийKnowledge check
Запрос уже две минуты показан в Web UI со state QUEUED и прогрессом 0%. Имеет ли смысл сразу начинать оптимизировать его SQL, и почему?
ОтветAnswer
Нет, не имеет. State QUEUED означает, что запрос ещё не начал исполнение: он стоит в очереди resource group и ждёт свободного слота на кластере. На этой стадии Trino даже не построил распределённый план и не назначил задачи воркерам, поэтому ни структура SQL, ни план, ни данные на ситуацию не влияют. Оптимизация запроса (переписывание SQL, сбор статистики, смена join-стратегии) ускоряет фазу RUNNING, но никак не сокращает ожидание в очереди. Реальные причины QUEUED — лимиты resource group (maxRunning достигнут конкурентными запросами) или нехватка ресурсов кластера. Поэтому первый шаг диагностики — всегда посмотреть на поле State в списке: оно отделяет проблемы планирования и данных (state RUNNING) от проблем конкуренции за ресурсы (state QUEUED), а лечатся эти два класса совершенно по-разному — в одном случае работают с запросом, в другом с конфигурацией resource groups или мощностью кластера.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Запрос в списке Web UI уже несколько минут показан со state QUEUED. Что это означает?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 6