Концепции Trino#

Обзор#

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

Хотя statements и queries понять достаточно легко, как конечному пользователю вам следует быть знакомым с такими концепциями, как stages и splits, чтобы в полной мере использовать возможности Trino для выполнения эффективных запросов. Как администратору Trino или участнику разработки Trino, вам также необходимо понимать, как концепции stages в Trino соотносятся с tasks и как tasks содержат набор drivers, которые обрабатывают данные.

Этот раздел предоставляет чёткие определения основных концепций, на которые ссылается документация Trino. Разделы отсортированы от наиболее общих к наиболее специфичным.

Note

Книга Trino: The Definitive Guide и исследовательская статья Presto: SQL on Everything могут предоставить дополнительную информацию о Trino и используемых концепциях.

Architecture#

Trino — это распределённый query engine, который обрабатывает данные параллельно на нескольких серверах. Существует два типа серверов Trino: coordinators и workers. В следующих разделах описываются эти серверы и другие компоненты архитектуры Trino.

Cluster#

Кластер Trino состоит из нескольких Trino nodes — одного coordinator и нуля или более workers. Пользователи подключаются к coordinator с помощью своего инструмента для выполнения SQL запросов. Coordinator взаимодействует с workers. Coordinator и workers получают доступ к подключённым data sources. Этот доступ настраивается в catalogs.

Обработка каждого запроса является stateful-операцией. Нагрузка оркестрируется coordinator и распределяется параллельно между всеми workers в кластере. Каждый node запускает Trino в одном экземпляре JVM, а обработка дополнительно распараллеливается с использованием потоков.

Node#

Любой сервер Trino в конкретном кластере Trino считается node этого cluster. Технически это относится к Java-процессу, в котором выполняется программа Trino, однако термин node часто используется для обозначения компьютера, на котором запущен этот процесс, поскольку рекомендуется запускать только один процесс Trino на одном компьютере.

Coordinator#

Coordinator Trino — это сервер, который отвечает за parsing statements, planning queries и управление worker-nodes Trino. Это «мозг» установки Trino, а также node, к которому подключается клиент для отправки statements на выполнение. Каждая установка Trino должна иметь один coordinator и один или несколько workers. Для целей разработки или тестирования один экземпляр Trino может быть настроен на выполнение обеих ролей.

Coordinator отслеживает активность на каждом worker и координирует выполнение query. Coordinator создаёт логическую модель запроса, включающую серию stages, которая затем преобразуется в серию связанных tasks, выполняемых на кластере Trino workers.

Coordinators взаимодействуют с workers и клиентами с помощью REST API.

Worker#

Worker Trino — это сервер в установке Trino, который отвечает за выполнение tasks и обработку данных. Worker nodes получают данные из connectors и обмениваются промежуточными данными друг с другом. Coordinator отвечает за получение результатов от workers и возврат финальных результатов клиенту.

Когда процесс Trino worker запускается, он объявляет себя (discovery) серверу coordinator, что делает его доступным для coordinator Trino для выполнения tasks.

Workers взаимодействуют с другими workers и coordinators Trino с использованием REST API.

Client#

Clients позволяют подключаться к Trino, отправлять SQL-запросы и получать результаты. Clients могут получать доступ ко всем настроенным источникам данных с помощью catalogs. Clients могут быть полнофункциональными клиентскими приложениями либо client drivers и libraries, которые позволяют подключаться из любого приложения, поддерживающего данный драйвер, или даже из собственного пользовательского приложения или скрипта.

Client applications включают инструменты командной строки, desktop-приложения, web-приложения и software-as-a-service решения с такими возможностями, как интерактивное написание SQL-запросов в редакторах, а также богатые пользовательские интерфейсы для графического создания запросов, выполнения запросов и отображения результатов, визуализации с помощью диаграмм и графиков, создания отчётов и dashboard.

Client-приложение, которое поддерживает другие query languages или пользовательские интерфейсные компоненты для построения запроса, должно переводить каждый запрос в SQL, поддерживаемый Trino.

Более подробная информация доступна в документации Trino client.

Plugin#

Trino использует plugin-архитектуру для расширения своих возможностей и интеграции с различными источниками данных и другими системами. Подробности о различных типах plugins, их установке, удалении и других аспектах доступны в документации Plugin.

Data source#

Trino — это query engine, который можно использовать для выполнения запросов к множеству различных источников данных. К ним относятся data lakes и lakehouses, многочисленные системы управления реляционными базами данных, key-value хранилища и многие другие data stores.

Полный список с более подробной информацией по каждому источнику данных доступен на сайте Trino.

Data sources предоставляют данные, которые Trino может запрашивать. Настройте catalog с необходимым Trino connector для конкретного источника данных, чтобы получить доступ к данным. После этого можно использовать любой поддерживаемый client, чтобы выполнять SQL-запросы к источникам данных с использованием возможностей вашего клиента.

В этой документации вы будете встречать такие термины, как connector, catalog, schema и table. Эти фундаментальные концепции описывают модель конкретного источника данных в Trino и рассматриваются в следующем разделе.

Connector#

Connector адаптирует Trino к источнику данных, например к data lake на основе Hadoop/Hive или Apache Iceberg, или к реляционной базе данных, такой как PostgreSQL. Connector можно рассматривать аналогично драйверу для базы данных. Это реализация service provider interface (SPI) Trino, которая позволяет Trino взаимодействовать с ресурсом через стандартный API.

Trino содержит множество встроенных connectors:

Каждый catalog использует определённый connector. Если вы посмотрите на файл конфигурации catalog, то увидите, что каждый из них содержит обязательное свойство connector.name, значение которого определяет используемый connector.

Catalog#

Catalog Trino — это набор конфигурационных свойств, используемых для доступа к конкретному источнику данных, включая необходимый connector и другие детали, такие как credentials и URL.

Catalogs определяются в properties-файлах, которые хранятся в директории конфигурации Trino. Имя properties-файла определяет имя catalog. Например, properties-файл etc/example.properties создаёт catalog с именем example.

Вы можете настроить и использовать множество catalogs, с одинаковыми или разными connectors, для доступа к различным источникам данных. Например, если у вас есть два data lakes, вы можете настроить два catalogs в одном кластере Trino, оба использующие Hive connector, что позволит выполнять запросы к данным из обоих кластеров, даже в рамках одного SQL-запроса.

Также можно использовать Hive connector для одного catalog, чтобы получить доступ к data lake, и использовать Iceberg connector для другого catalog, чтобы получить доступ к data lakehouse. Или можно настроить разные catalogs для доступа к различным базам данных PostgreSQL.

Комбинация различных catalogs определяется только вашими потребностями в доступе к различным источникам данных.

Catalog содержит одну или несколько schemas, которые в свою очередь содержат объекты, такие как tables, views или materialized views. При обращении к объектам, таким как tables, в Trino всегда используется fully-qualified имя, которое начинается с catalog.

Например, fully-qualified имя таблицы example.test_data.test относится к таблице test в schema test_data в catalog example.

Schema#

Schemas — это способ организации tables. Вместе catalog и schema определяют набор tables и других объектов, к которым можно выполнять запросы.

При доступе к Hive или реляционной базе данных, такой как MySQL, через Trino, schema соответствует той же концепции в целевой базе данных.

Другие типы connectors могут организовывать tables в schemas способом, который имеет смысл для базового источника данных.

Table#

Table — это набор неупорядоченных строк, которые организованы в именованные столбцы с types.

Это аналогично любой реляционной базе данных. Отображение типов данных из источника в Trino (type mapping) определяется connector, может отличаться между connectors и документируется в документации конкретного connector, например в разделе type mapping в PostgreSQL connector.

Модель выполнения запросов#

Trino выполняет SQL statements и преобразует их в queries, которые выполняются в распределённом кластере, состоящем из coordinator и workers.

Statement#

Trino выполняет SQL statements, совместимые со стандартом ANSI. Когда документация Trino ссылается на statement, имеется в виду statement, определённый стандартом ANSI SQL, который состоит из clauses, expressions и predicates.

Некоторым читателям может быть интересно, почему в этом разделе перечислены отдельные концепции statements и queries.

Это необходимо, потому что в Trino statements обозначают лишь текстовое представление SQL-выражения.

Когда statement выполняется, Trino создаёт query вместе с query plan, который затем распределяется между несколькими Trino workers.

Query#

Когда Trino выполняет parsing statement, он преобразует его в query и создаёт распределённый query plan, который затем реализуется как серия взаимосвязанных stages, выполняющихся на Trino workers.

Когда вы получаете информацию о query в Trino, вы получаете снимок состояния всех компонентов, участвующих в формировании result set в ответ на statement.

Разница между statement и query достаточно проста. Statement можно рассматривать как SQL-текст, который передаётся в Trino, тогда как query относится к конфигурации и компонентам, созданным для выполнения этого statement.

Query включает stages, tasks, splits, connectors и другие компоненты и источники данных, которые совместно работают для получения результата.

Stage#

Когда Trino выполняет query, он разбивает выполнение на иерархию stages.

Например, если Trino необходимо агрегировать данные из одного миллиарда строк, хранящихся в Hive, он создаёт root stage, который агрегирует результаты нескольких других stages, каждая из которых реализует разные части распределённого query plan.

Иерархия stages, составляющих query, напоминает дерево.

Каждый query имеет root stage, который отвечает за агрегирование результатов других stages.

Stages используются coordinator для моделирования распределённого query plan, однако сами stages не выполняются на Trino workers.

Task#

Как упоминалось в предыдущем разделе, stages моделируют определённую часть распределённого query plan, но сами stages не выполняются на Trino workers.

Чтобы понять, как выполняется stage, необходимо понимать, что stage реализуется как серия tasks, распределённых по сети Trino workers.

Tasks являются «рабочей силой» архитектуры Trino, поскольку распределённый query plan разбивается на серию stages, которые затем преобразуются в tasks, выполняющие обработку splits.

Task в Trino имеет входы и выходы, и так же, как stage может выполняться параллельно с помощью нескольких tasks, task выполняется параллельно с использованием серии drivers.

Split#

Tasks работают со splits, которые представляют собой части более крупного набора данных.

Stages на самом нижнем уровне распределённого query plan получают данные через splits из connectors, а промежуточные stages на более высоком уровне получают данные из других stages.

Когда Trino планирует выполнение query, coordinator запрашивает у connector список всех splits, доступных для таблицы.

Coordinator отслеживает, какие машины выполняют какие tasks, и какие splits обрабатываются какими tasks.

Driver#

Tasks содержат один или несколько параллельных drivers.

Drivers обрабатывают данные и объединяют operators для формирования output, который затем агрегируется task и передаётся другой task в другой stage.

Driver — это последовательность экземпляров operator, или, другими словами, физический набор operators в памяти.

Это самый низкий уровень параллелизма в архитектуре Trino.

Driver имеет один вход и один выход.

Operator#

Operator потребляет, преобразует и производит данные.

Например, table scan получает данные из connector и производит данные, которые могут быть использованы другими operators, а filter operator потребляет данные и создаёт подмножество, применяя predicate к входным данным.

Exchange#

Exchanges передают данные между nodes Trino для различных stages выполнения query.

Tasks помещают данные в output buffer и получают данные от других tasks с помощью exchange client.