Learning Platform
Глоссарий Troubleshooting
Урок 15.07 · 22 мин
Средний
deploymenttrino-gatewayroutingoperations

Trino Gateway: маршрутизация, балансировка, blue/green апгрейды

В модуле про fault tolerance мы пришли к идее нескольких кластеров: отдельный интерактивный кластер с retry-policy=NONE и отдельный batch-кластер с retry-policy=TASK. Но у такого подхода есть нерешённая проблема: клиентам теперь нужно знать про несколько кластеров и выбирать, к какому подключаться. А ещё — что делать при апгрейде кластера, не роняя пользователей.

Обе проблемы решает Trino Gateway — балансировщик, прокси и маршрутизирующий шлюз для нескольких кластеров Trino. Этот урок разбирает, что даёт Gateway: единый URL, маршрутизацию и балансировку, привязку запроса к кластеру по query id и апгрейды без простоя.


Зачем нужен Gateway

Без Gateway множество кластеров — это головная боль для клиентов. Каждый BI-инструмент, каждое приложение должно знать адреса всех кластеров и логику «интерактив — туда, batch — сюда». Добавили кластер, вывели кластер на обслуживание — правь конфигурацию у всех клиентов. Это не масштабируется.

Trino Gateway ставится перед кластерами Trino. Клиенты подключаются не к кластерам, а к Gateway — по одному URL. Gateway уже сам решает, на какой кластер направить запрос. Для клиента множество кластеров становится невидимым: он видит «один Trino», а за шлюзом — сколько угодно кластеров под разные нагрузки.

Trino Gateway: единый URL перед множеством кластеров
КлиентыBI-инструменты, приложения, Trino CLI. Все подключаются к одному URL Gateway, про отдельные кластеры не знают
один URL
Trino GatewayБалансировщик и маршрутизирующий шлюз. Принимает все запросы и решает, на какой кластер их направить
маршрутизация
Кластер AНапример, интерактивный кластер для дашбордов
Кластер BНапример, batch-кластер с FTE для тяжёлых ETL
NOTE

Trino Gateway — отдельный продукт со своим репозиторием (trinodb/trino-gateway) и собственной версионностью, не совпадающей с номерами релизов Trino. Это не часть ядра Trino, а самостоятельный компонент, который ставят рядом.


Маршрутизация и балансировка

Главная работа Gateway — решить, на какой кластер отправить пришедший запрос. Gateway группирует кластеры в routing groups (группы маршрутизации) — например, группа interactive и группа batch — и направляет запрос в подходящую группу, а внутри группы балансирует нагрузку между её кластерами.

Как Gateway выбирает группу — поддерживается несколько стратегий маршрутизации:

Стратегия маршрутизацииКак выбирается группа/кластер
По HTTP-заголовкуклиент указывает целевую routing group заголовком запроса
Правила (rules engine)набор правил на MVEL-выражениях сопоставляет атрибуты запроса с группой
Внешний сервисрешение о маршрутизации делегируется внешнему сервису
По нагрузкезапрос направляется на менее загруженный кластер

Внутри выбранной routing group Gateway распределяет запросы между её кластерами — adaptive (с учётом загрузки) или round-robin. Так Gateway совмещает две функции: маршрутизацию (в правильную группу под тип нагрузки) и балансировку (равномерно по кластерам внутри группы).

Практический смысл — ровно тот, к которому мы шли в модуле про fault tolerance. Routing group interactive ведёт на NONE-кластеры, группа batch — на TASK-кластеры с FTE. Клиент дашборда и клиент тяжёлого ETL ходят на один URL Gateway, а тот разводит их по кластерам с подходящей retry-policy. Разделение кластеров остаётся прозрачным.


Привязка запроса к кластеру по query id

Тонкий, но важный механизм. Протокол Trino — не «один запрос = одно HTTP-обращение». Клиент отправляет statement, получает в ответе query id и nextUri, а потом многократно опрашивает nextUri, забирая страницы результата. То есть один запрос — это серия HTTP-обращений во времени.

Возникает проблема для шлюза. Запрос исполняется на конкретном кластере. Если Gateway первое обращение направит на кластер A, а последующие polling-обращения того же запроса по балансировке улетят на кластер B — там про этот запрос ничего не знают, и всё ломается.

Gateway решает это привязкой по query id. Из ответа на первое обращение Gateway извлекает query id и запоминает, на какой кластер этот запрос ушёл. Все последующие обращения с тем же query id Gateway направляет на тот же кластер. Запрос «прилипает» к своему кластеру на всё время жизни.

Query-id affinity: запрос прилипает к своему кластеру
Первое обращение -> кластер выбран, query id запомненGateway маршрутизирует первое обращение запроса на кластер, извлекает из ответа query id и запоминает связку query id -> кластер
клиент опрашивает nextUri
Все обращения с тем же query id -> тот же кластерPolling-обращения с известным query id Gateway направляет на тот же кластер A, где запрос реально исполняется. На другой кластер они не уйдут

Без query-id affinity балансировка ломала бы каждый запрос; с ней балансировка применяется к выбору кластера для нового запроса, а уже идущий запрос остаётся на своём кластере.


Состояние и health checks

Gateway — не просто статичный прокси, он ведёт состояние и следит за здоровьем кластеров.

Состояние Gateway хранит во внешней базе данных — PostgreSQL, MySQL или Oracle. Там лежат конфигурация кластеров, привязки запросов, история. Схему БД Gateway мигрирует сам (через Flyway). Внешняя БД означает, что несколько экземпляров Gateway могут работать с общим состоянием — сам Gateway не становится единой точкой отказа.

Health checks. Gateway периодически проверяет здоровье кластеров за ним. Нездоровый кластер — упавший, перегруженный, выведенный на обслуживание — Gateway исключает из маршрутизации: новые запросы на него не пойдут, пока он не вернётся в строй. Это автоматическая защита: сбойный кластер не получает трафик, а клиенты этого даже не замечают.

Аутентификация на самом Gateway тоже есть — он поддерживает OAuth/OIDC, form-based вход, JWT, — так что Gateway становится и единой точкой входа, и единой точкой контроля доступа к парку кластеров.


Docker Compose: быстрый стенд для проверки Gateway

Blue/green апгрейды без простоя

Самая ценная эксплуатационная возможность Gateway — апгрейды кластеров без простоя. Trino выходит часто (раз в 1-4 недели), и обновлять кластер, роняя пользователей на каждый релиз, недопустимо.

Gateway делает апгрейд по схеме blue/green. Идея:

  1. Рядом с работающим («blue») кластером поднимается новый («green») кластер — уже на новой версии Trino.
  2. Green-кластер добавляется за Gateway. Gateway начинает направлять новые запросы на green-кластер.
  3. Blue-кластер при этом не убивают сразу — он доисполняет уже идущие на нём запросы (привязанные к нему по query id). Дренаж.
  4. Когда на blue-кластере не осталось активных запросов, его выводят. Апгрейд завершён.
Blue/green апгрейд за Gateway: без простоя
1. Поднят green-кластер на новой версииРядом с работающим blue-кластером разворачивается green-кластер новой версии Trino и добавляется за Gateway
Gateway переводит новые запросы
2. Новые запросы -> green, blue дренируетGateway направляет новые запросы на green-кластер. Blue доисполняет уже идущие на нём запросы — никого не обрывает
blue опустел
3. Blue выведен, кластер на новой версииКогда на blue не осталось активных запросов, его выводят. Пользователи апгрейда не заметили — простоя не было

Ключ к тому, что это работает без потери запросов, — та самая query-id affinity. Запросы, начатые на blue-кластере, остаются привязаны к нему и спокойно доисполняются, пока новые уходят на green. Простоя нет, оборванных запросов нет — пользователи апгрейда просто не замечают. Тем же приёмом делают canary-выкатки (часть трафика на новую версию для проверки) и прозрачное изменение мощности кластеров.

TIP

Связка через весь курс. Gateway даёт единый URL и blue/green апгрейды; query-id affinity делает апгрейды безопасными; routing groups разводят интерактив и batch по кластерам с разной retry-policy из модуля fault tolerance; graceful shutdown из урока про Kubernetes корректно гасит дренируемые ноды. Эти механизмы складываются в одну эксплуатационную картину: парк кластеров Trino, который обновляется и масштабируется, не роняя пользователей.


Попробуй сам

Поставь Trino Gateway перед несколькими кластерами на тестовом стенде.

  1. Подними два небольших кластера Trino (через docker-compose или Helm) — например, один пометь как интерактивный, другой как batch. Затем подними Trino Gateway с внешней БД (PostgreSQL) для его состояния.
  2. Зарегистрируй оба кластера за Gateway, распредели их по routing groups. Подключи Trino CLI к URL Gateway и выполни запросы — проверь, что они доходят до кластеров.
  3. Проверь query-id affinity: запусти запрос подлиннее и проследи, что все polling-обращения идут на один и тот же кластер, а не разбредаются.
  4. Сымитируй blue/green: добавь третий «green» кластер за Gateway, переведи на него новые запросы и убедись, что запросы, уже идущие на «blue», доживают на нём. Затем выведи «blue».

Цель — увидеть, что Gateway прячет множество кластеров за единым URL и делает апгрейды без простоя за счёт привязки запросов к кластерам.


Проверка знанийKnowledge check
Зачем Trino Gateway привязывает запрос к кластеру по query id, и почему именно этот механизм делает возможными blue/green апгрейды без простоя?
ОтветAnswer
Gateway привязывает запрос к кластеру по query id из-за устройства протокола Trino. Один запрос — это не одно HTTP-обращение: клиент отправляет statement, получает в ответе query id и nextUri, а затем многократно опрашивает nextUri, забирая страницы результата. То есть запрос — это серия HTTP-обращений, растянутая во времени, и весь он исполняется на одном конкретном кластере. Если бы Gateway первое обращение направил на кластер A, а последующие polling-обращения того же запроса по балансировке улетели на кластер B, там про этот запрос ничего не знают — и запрос сломался бы. Поэтому Gateway из ответа на первое обращение извлекает query id и запоминает связку query id -> кластер; все последующие обращения с тем же query id он направляет на тот же кластер. Запрос прилипает к своему кластеру на всё время жизни, а балансировка применяется только к выбору кластера для нового запроса. Этот же механизм делает возможными blue/green апгрейды без простоя. Blue/green апгрейд устроен так: рядом с работающим blue-кластером поднимается green-кластер на новой версии Trino, добавляется за Gateway, и Gateway начинает направлять новые запросы на green; при этом blue-кластер не убивают сразу — он доисполняет уже идущие на нём запросы, дренируется, и только когда на нём не осталось активных запросов, его выводят. Безопасным без потери запросов это делает именно query-id affinity: запросы, начатые на blue-кластере, остаются привязаны к нему по своему query id и спокойно доисполняются там, пока новые запросы уходят на green. Без привязки по query id polling-обращения дренируемых запросов разбредались бы между кластерами и ломались бы при переключении трафика. С ней простоя нет, оборванных запросов нет, и пользователи апгрейда его просто не замечают; тем же приёмом делают canary-выкатки и прозрачное изменение мощности кластеров.

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

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

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

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

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

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