Learning Platform
Глоссарий Troubleshooting
Урок 16.06 · 22 мин
Средний
trino-clijdbcpython-clientdbt-trino

Клиенты: Trino CLI, JDBC, trino-python-client, dbt-trino

Trino без клиента — мотор без колёс. Координатор принимает запросы только через HTTP, и любой клиент — будь то CLI в терминале, BI-инструмент, Python-скрипт или dbt — это надстройка над одним и тем же протоколом. Этот урок разбирает четыре основных клиента и, главное, общий client protocol под ними. Понимать протокол важно: он объясняет, почему клиент ведёт себя именно так, и почему «зависший» клиент почти никогда не означает зависший Trino.


Client protocol: что под всеми клиентами

Координатор Trino предоставляет HTTP/REST-протокол. Он устроен вокруг polling (опроса), и это его определяющая черта.

Клиент отправляет SQL-текст одним HTTP-запросом (POST /v1/statement). Trino не блокирует соединение до конца запроса. Вместо этого он немедленно отвечает JSON-документом, в котором есть nextUri — ссылка, по которой надо запросить продолжение. Клиент идёт по nextUri, получает следующий документ: там либо первая порция строк результата и снова nextUri, либо состояние «ещё выполняется» и снова nextUri. Клиент опрашивает nextUri в цикле, пока не выберет все строки и не получит документ без nextUri — это конец.

Client protocol: цикл polling
КлиентЛюбой клиент: CLI, JDBC-драйвер, Python-клиент. Отправляет SQL-текст одним POST-запросом.
/v1/statement
КоординаторПринимает запрос, сразу отвечает JSON со ссылкой nextUri. Соединение не держится открытым до конца запроса.
клиент опрашивает nextUri в цикле
GET nextUriКаждый запрос по nextUri возвращает либо порцию строк и новый nextUri, либо статус выполнения и новый nextUri.
пока есть nextUri
Документ без nextUriОтсутствие nextUri означает: результат выбран полностью, запрос завершён.

Из устройства протокола следуют важные практические выводы:

  • Запрос продолжается на кластере, даже если клиент перестал опрашивать. Это объясняет «зависшие» дашборды: BI-инструмент мог отвалиться по своему таймауту, а запрос на Trino всё ещё идёт — его видно в Web UI со state RUNNING.
  • Результат стримится порциями. Клиент получает строки по мере готовности, ему не нужно ждать полной материализации. Поэтому CLI начинает печатать первые строки большого результата почти сразу.
  • Состояние запроса живёт на координаторе. Клиент держит только query id и текущий nextUri. Сетевой сбой между двумя опросами не убивает запрос.
  • Любой клиент — это реализация этого цикла. CLI, JDBC, Python-клиент отличаются языком и удобствами, но внутри делают одно и то же.
NOTE

Polling-протокол объясняет ключевое правило диагностики: «клиент завис» и «Trino завис» — разные вещи. Если клиент не отвечает, первым делом откройте Web UI и найдите запрос по query id. State RUNNING означает, что Trino работает и проблема на стороне клиента или сети; FINISHED означает, что запрос давно готов, а клиент просто перестал забирать результат. Чинить нужно ту сторону, где реально проблема.


Trino CLI

Trino CLI — официальный клиент командной строки, поставляемый как self-executable JAR (запускается напрямую без отдельной установки JVM-обвязки). Это основной инструмент для интерактивной работы, отладки и скриптов.

# Интерактивная сессия
trino --server https://trino.example.com:8443 \
      --user analyst --catalog iceberg --schema analytics

# Один запрос и выход — удобно для скриптов
trino --server https://trino.example.com:8443 \
      --catalog tpch --schema sf1 \
      --execute "SELECT count(*) FROM lineitem"

# Запрос из файла, вывод без рамок для пайплайна
trino --server https://trino.example.com:8443 \
      --catalog iceberg --schema analytics \
      --file report.sql --output-format CSV

В интерактивном режиме CLI показывает прогресс-бар запроса — это тот же прогресс, что в Web UI, отрисованный в терминале. Полезные флаги: --output-format (ALIGNED для человека, CSV/TSV/JSON для пайплайнов), --session для session-параметров, --execute и --file для неинтерактивного запуска. Внутри CLI работает по описанному protocol: POST запроса, цикл опроса nextUri, печать порций по мере прихода.


JDBC-драйвер

Для JVM-приложений и большинства BI-инструментов Trino предоставляет JDBC-драйвер. Это стандартный JDBC: приложение работает с Connection, Statement, ResultSet, не зная про polling, — драйвер прячет цикл опроса под привычным API.

String url = "jdbc:trino://trino.example.com:8443/iceberg/analytics";
Properties props = new Properties();
props.setProperty("user", "analyst");
props.setProperty("password", "secret");
props.setProperty("SSL", "true");

try (Connection conn = DriverManager.getConnection(url, props);
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery(
         "SELECT event_type, count(*) AS cnt " +
         "FROM events GROUP BY event_type")) {
    while (rs.next()) {
        System.out.println(rs.getString("event_type")
                           + " = " + rs.getLong("cnt"));
    }
}

JDBC URL кодирует адрес координатора и опционально каталог со схемой по умолчанию; параметры подключения (учётные данные, TLS, session properties) передаются через Properties. Через JDBC к Trino подключаются Tableau, DBeaver, Apache Superset и другие JVM-совместимые инструменты. Важная деталь версионирования: с 2025 года JDBC-драйвер Trino требует Java 11 или 17 — это отдельное требование, не совпадающее с версией Java серверной части (сервер на актуальных релизах требует более новую JDK).


trino-python-client

Для Python-экосистемы есть официальный trino-python-client. Он работает на Python 3.9+ и PyPy и предлагает три уровня API под разные задачи.

# DBAPI 2.0 — стандартный для Python интерфейс к БД
from trino.dbapi import connect

conn = connect(
    host="trino.example.com",
    port=8443,
    user="analyst",
    catalog="iceberg",
    schema="analytics",
    http_scheme="https",
)
cur = conn.cursor()
cur.execute("SELECT event_type, count(*) FROM events GROUP BY 1")
for event_type, cnt in cur.fetchall():
    print(event_type, cnt)

Три уровня:

  • Low-level client — прямая работа с protocol, максимальный контроль над опросом и страницами результата.
  • DBAPI 2.0 — стандартный для Python интерфейс к БД (connect, cursor, execute, fetchall); им пользуются чаще всего, и его понимают инструменты, ожидающие DBAPI-совместимое соединение.
  • SQLAlchemy-адаптер — позволяет работать с Trino через SQLAlchemy; так Trino подключается к инструментам, построенным поверх SQLAlchemy.

Python-клиент — основа для скриптов извлечения данных, ноутбуков и пайплайнов оркестрации, где шаг — это запрос к Trino.


Сессии и параметры запроса

У всех клиентов есть общее понятие, которое стоит разобрать, — сессия. Когда клиент подключается к Trino, у соединения есть контекст: каталог и схема по умолчанию, часовой пояс, язык и, главное, session properties — параметры, влияющие на поведение движка для запросов этой сессии.

Session properties — это рычаги тюнинга, которые применяются без перезапуска кластера и только к текущему соединению. Например, join_distribution_type принудительно задаёт тип распределения join, query_max_memory ограничивает память запроса, join_reordering_strategy управляет переупорядочиванием join. В CLI их задают флагом --session или командой SET SESSION в сессии; в JDBC — через Properties; в Python-клиенте — аргументом session_properties; в profiles.yml dbt-trino — отдельной секцией. Под капотом любой клиент просто передаёт их координатору вместе с запросом.

Это объясняет важную деталь диагностики из урока про Web UI: на странице деталей запроса видны session-параметры, с которыми он был запущен. Неожиданное поведение запроса часто объясняется именно случайно выставленным session property — например, инструмент мог проставить свой join_distribution_type, и план запроса оказался не таким, как ожидалось. Поэтому при разборе странного плана session-параметры проверяют одними из первых.

WARNING

Session properties удобны для экспериментов и точечных обходов, но это не способ постоянной настройки кластера. Если каждый клиент проставляет свои session-параметры, поведение Trino становится непредсказуемым и зависит от того, кто и как подключился. Постоянные настройки место в конфигурации кластера, а session properties — для разовых случаев: проверить гипотезу тюнинга, обойти конкретную проблему конкретного запроса.


dbt-trino

dbt: адаптер dbt-trino — конфигурация и materialization-стратегии

dbt-trino — адаптер, делающий Trino движком трансформаций для dbt. dbt описывает модели как SQL-файлы со ссылками ref(), строит из них DAG и исполняет в правильном порядке; адаптер транслирует это в конкретный движок. dbt-trino делает движком Trino.

# profiles.yml — профиль подключения dbt к Trino
analytics_project:
  target: prod
  outputs:
    prod:
      type: trino
      host: trino.example.com
      port: 8443
      user: dbt_runner
      http_scheme: https
      catalog: iceberg
      schema: analytics
      threads: 8

Связка особенно естественна именно с Trino из-за его федеративности. dbt-модель может в одном SELECT соединить таблицы из разных каталогов — Iceberg-факты и dimension из PostgreSQL, — и dbt построит из такой модели материализованную витрину. Получается ELT, где T работает поверх нескольких источников сразу, без предварительного сведения данных в одно хранилище. Параметр threads задаёт, сколько моделей dbt-trino отправляет на Trino параллельно; Trino-кластер с его MPP-исполнением такую параллельную нагрузку рассчитан принимать.


Какой клиент когда

Все четыре клиента говорят по одному протоколу — выбор определяется задачей.

ЗадачаКлиент
Интерактивная отладка, ad-hoc, шелл-скриптыTrino CLI
BI-инструменты, JVM-приложенияJDBC-драйвер
Python-скрипты, ноутбуки, пайплайны оркестрацииtrino-python-client
ELT-трансформации, моделирование витринdbt-trino
Операционные дашборды по данным lakehouseGrafana Trino Data Source Plugin
Клиенты над единым client protocol
Trino CLIИнтерактивный терминальный клиент. Отладка, ad-hoc-запросы, скрипты.
JDBC-драйверСтандартный JDBC для JVM-приложений и BI-инструментов. Прячет polling под Connection/ResultSet.
trino-python-clientPython-клиент: low-level, DBAPI 2.0, SQLAlchemy. Скрипты и ноутбуки.
dbt-trinoАдаптер dbt: Trino как движок ELT-трансформаций, в том числе федеративных.
все говорят по одному протоколу
Client protocol (HTTP polling)POST запроса, цикл опроса nextUri, стриминг порций результата. Единый протокол под всеми клиентами.
Координатор TrinoПринимает запросы по HTTP, планирует, раздаёт задачи воркерам, отдаёт результат порциями.
TIP

Какой бы клиент вы ни использовали, в продакшене соединение почти всегда идёт через TLS (https) и с аутентификацией. В примерах выше это http_scheme: https, SSL=true, порт 8443. Поскольку под всеми клиентами один протокол, настройки безопасности у них концептуально одинаковы — меняется только синтаксис их передачи: флаги CLI, свойства JDBC, аргументы Python-клиента, поля profiles.yml.


Попробуй сам

Подключитесь к локальному Trino двумя разными клиентами и убедитесь, что под ними один протокол.

  1. Через Trino CLI выполните запрос, который вернёт много строк, например SELECT * FROM tpch.sf1.orders LIMIT 200000. Заметьте: первые строки печатаются почти сразу, не дожидаясь конца, — это стриминг порций.
  2. Установите pip install trino и из Python через DBAPI 2.0 выполните SELECT count(*) FROM tpch.sf1.lineitem. Это тот же кластер, другой клиент.
  3. Запустите долгий запрос через CLI и, не дожидаясь конца, прервите CLI по Ctrl-C. Откройте Web UI: что показывает state этого запроса сразу после прерывания клиента?
  4. Снова запустите долгий запрос и в Web UI на странице деталей в блоке Overview найдите поле источника (source). Сравните, как обозначены запросы из CLI и из Python-клиента.
  5. Запустите тот же запрос с флагом --output-format JSON и посмотрите, как меняется представление результата.

Цель — на практике увидеть, что клиент — это лишь надстройка над protocol, и что прерывание клиента не равно остановке запроса на Trino.


Проверка знанийKnowledge check
Дашборд Tableau, подключённый к Trino по JDBC, "завис": крутится индикатор загрузки и ничего не показывает. Опираясь на устройство client protocol, опишите, как за минуту определить, на чьей стороне проблема — Trino или клиента.
ОтветAnswer
Ключ к ответу — устройство client protocol. Trino работает по polling: координатор не держит соединение открытым до конца запроса, а отдаёт ссылки nextUri, которые клиент опрашивает в цикле; состояние запроса при этом живёт на координаторе, а не в клиенте. Из этого следует, что запрос на кластере продолжается независимо от того, опрашивает его клиент или нет, а значит "клиент завис" и "Trino завис" — это разные ситуации, и их можно различить. Порядок диагностики такой. Сначала открыть Web UI координатора и найти этот запрос в списке — по пользователю, по тексту SQL или по времени; у Tableau-запросов в поле source обычно видно, что они пришли через JDBC. Дальше решает поле State. Если State равен RUNNING, Trino исправно выполняет запрос — крутящийся индикатор Tableau означает лишь, что запрос пока не закончился; смотрят прогресс и горячую стадию, и если запрос объективно тяжёлый, это вопрос тюнинга, а не зависания. Если State равен FINISHED, запрос давно готов, и проблема целиком на стороне клиента или сети: Tableau либо перестал опрашивать nextUri, либо ответ к нему не доходит — нужно разбираться с клиентом, его таймаутами и сетью между ним и координатором. Если State равен FAILED, у запроса есть код и текст ошибки — их и показывают как причину. Если же запроса в Web UI вообще нет, значит он не дошёл до координатора, и проблема ещё ближе к клиенту: конфигурация JDBC-подключения, адрес, учётные данные или сеть. Таким образом одно поле State в Web UI за минуту указывает, какую сторону чинить, и избавляет от бессмысленной оптимизации SQL там, где запрос на самом деле давно завершён.

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

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Как устроен client protocol Trino, по которому работают все клиенты?

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

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

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

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