Learning Platform
Глоссарий Troubleshooting
Урок 04.04 · 20 мин
Средний
connectorecosystemlakehousefederation

Обзор экосистемы коннекторов

Trino поставляется с десятками коннекторов, и за каждым стоит источник со своей природой. Реляционная СУБД, файл на object storage, топик Kafka — это принципиально разные модели данных. Один коннектор читает строки через SQL по сети, другой парсит колоночные файлы, третий вычитывает поток сообщений. Эти различия не косметические: они определяют, что от источника можно ждать по производительности и по семантике.

Этот урок даёт карту экосистемы по четырём большим категориям: object storage / lakehouse, RDBMS, NoSQL, streaming. Цель — не заучить список, а понять, чем категории отличаются и как выбор источника влияет на запрос.


Четыре категории источников

Категории коннекторов Trino
Object storageФайлы в S3, GCS, Azure под управлением табличного формата: Hive, Iceberg, Delta Lake, Hudi.
RDBMSРеляционные СУБД через JDBC: PostgreSQL, MySQL, SQL Server, Oracle и другие.
NoSQL / searchНереляционные хранилища: Cassandra, MongoDB, Redis, Elasticsearch, OpenSearch.
StreamingСистемы потоковой передачи сообщений: Kafka, Loki.

Категории различаются по трём осям, которые стоит держать в голове: умеет ли источник параллелить чтение, насколько богатый pushdown коннектор может реализовать, и есть ли у источника собственная статистика для оптимизатора. Дальше пройдём по категориям именно с этой меркой.


Object storage и lakehouse

Это категория, ради которой Trino чаще всего и разворачивают. Данные лежат файлами на object storage — S3, GCS, Azure Blob, HDFS. Сами по себе файлы это просто Parquet или ORC. Чтобы набор файлов стал «таблицей» с историей изменений и схемой, нужен табличный формат: Hive, Iceberg, Delta Lake или Hudi. Табличный формат хранит метаданные — какие файлы входят в таблицу, какая у неё схема, какие были снапшоты.

Коннекторы этой категории:

КоннекторЧто это
HiveСтарейший формат: метаданные в Hive Metastore, данные в ORC/Parquet/других форматах
IcebergСовременный открытый формат таблиц: снапшоты, time travel, schema evolution
Delta LakeФормат от Databricks: transaction log, deletion vectors, change data feed
HudiФормат с акцентом на upsert и инкрементальную обработку
LakehouseЕдиный коннектор, объединяющий Hive, Iceberg, Delta Lake и Hudi в одном catalog

Семантика этой категории: чтение хорошо параллелится (файлы и row-group-и становятся splits — много splits, много задач), pushdown богатый (для Parquet/ORC работает predicate и projection pushdown вплоть до пропуска row-group по min/max), статистика обычно есть (Iceberg и Delta поддерживают статистику и обновляют её при записи).

NOTE

Iceberg, Delta Lake и Hive — это НЕ базы данных. Это форматы таблиц поверх файлов в object storage. Их “метаданные” — список файлов, схема, снапшоты — лежат в Metastore или в специальном каталоге. Trino через коннектор читает эти метаданные, чтобы понять, что таблица собой представляет, а затем читает сами файлы данных.

Отдельно стоит упомянуть, что Trino перешёл на нативную файловую систему для object storage — собственные реализации доступа к S3, Azure, GCS. Старый Hadoop-based слой доступа удалён в релизе 481, так что актуальные кластеры используют только нативную ФС.


RDBMS: реляционные источники через JDBC

Вторая большая категория — реляционные СУБД: PostgreSQL, MySQL, MariaDB, SQL Server, Oracle, Redshift, ClickHouse, SingleStore, Snowflake, BigQuery, DuckDB, Exasol, Ignite. Большинство из них Trino читает через JDBC, и у этой категории своя характерная семантика.

Параллелизм чтения здесь по умолчанию ограничен. Реляционная таблица для JDBC-коннектора обычно становится одним split — Trino открывает одно соединение и тянет результат потоком. В отличие от object storage, где таблица из тысяч файлов разбивается на тысячи splits, JDBC-источник не партиционируется параллельно «из коробки». Это нормально: реляционные источники чаще используют как dimension-таблицы (относительно небольшие), а не как fact-таблицы на миллиарды строк.

Зато pushdown в RDBMS-коннекторах особенно ценен. У источника есть полноценный SQL-движок — глупо тянуть всю таблицу в Trino, чтобы потом отфильтровать. Хорошие JDBC-коннекторы проталкивают в источник predicate, projection, нередко aggregation, иногда join между таблицами одного источника. Trino фактически переписывает часть запроса в SQL источника и отдаёт ему.

Это видно на EXPLAIN. Когда фильтр протолкнут, в плане у TableScan появляется встроенный предикат, а отдельного Filter-оператора нет:

EXPLAIN SELECT customer_id FROM postgresql.public.orders
WHERE status = 'PAID';
Fragment 0 [SOURCE]
    TableScan[table = postgresql:public.orders,
        constraint = (status = 'PAID')]
        customer_id := customer_id:bigint

Предикат status = 'PAID' ушёл в constraint самого TableScan — значит, фильтрацию выполнит PostgreSQL, и по сети к Trino придут только нужные строки. Без pushdown в плане был бы отдельный Filter, и Trino тянул бы всю таблицу.

WARNING

Помните про границу параллелизма JDBC-источников. Запрос вида “join большой fact-таблицы из PostgreSQL с чем-то ещё” может упереться в то, что fact-таблица читается одним соединением. Большие fact-данные лучше держать на object storage, а реляционные источники подключать ради dimension-таблиц и федерации.


NoSQL и поисковые движки

Третья категория — нереляционные хранилища: Cassandra, MongoDB, Redis и поисковые движки Elasticsearch, OpenSearch, а также Pinot и Druid. Их объединяет то, что родная модель данных не реляционная, и коннектор делает нетривиальную работу, представляя источник в виде таблиц со столбцами.

Cassandra устроена вокруг partition key и clustering columns — коннектор мапит keyspace на schema, а таблицу на таблицу, но за плоской табличной картинкой стоит специфика: эффективны запросы по ключу партиции, неэффективны полные сканы. MongoDB хранит документы переменной структуры — коннектор должен либо вывести схему по сэмплу документов, либо взять её из явного описания, а вложенные документы превращаются в тип ROW. Elasticsearch и OpenSearch — поисковые индексы; коннектор представляет индекс как таблицу и умеет передавать в движок поиска часть условий.

Общая мерка по нашим трём осям здесь даёт пёструю картину. Параллелизм бывает (Cassandra читается по token range, Elasticsearch по шардам), но pushdown и его семантика сильно зависят от источника, а полноценной статистики для CBO обычно нет.

ClickHouse: колоночная OLAP-база как альтернатива NoSQL для аналитики Поэтому к NoSQL-коннекторам стоит относиться с осторожностью: проверять по документации, какие условия проталкиваются, и не ждать, что оптимизатор построит идеальный план без статистики.


Streaming: Kafka и логи

Четвёртая категория — streaming. Главный представитель — Kafka: коннектор представляет топик как таблицу, где сообщения это строки. Сюда же относится Loki — коннектор к системе логов Grafana Loki.

Семантика streaming-источников особенная. Топик Kafka это не статичная таблица: в него постоянно дописываются сообщения. Чтение топика через Trino это снимок на момент запроса. Splits здесь естественно ложатся на разделы топика — каждый partition читается своей задачей, так что параллелизм определяется числом разделов. Сообщения нужно ещё и десериализовать (JSON, Avro и так далее) — это часть работы коннектора.

Streaming-коннекторы хороши для интерактивных запросов «что сейчас в потоке», для разбора и валидации данных, для разовых выборок. Но Trino — это OLAP-движок для аналитических запросов, а не stream-processing-система: непрерывную обработку потока с состоянием делают специализированные инструменты, а Trino даёт SQL-доступ к содержимому потока в моменте.

Kafka: топики, партиции и офсеты
Семантика категорий по трём осям
Object storageМного splits из файлов, богатый pushdown по Parquet/ORC, статистика у Iceberg и Delta.
RDBMS / JDBCПараллелизм по умолчанию ограничен одним split, зато сильный pushdown в SQL-движок источника.
NoSQL / searchПараллелизм и pushdown зависят от источника, статистики для CBO обычно нет.
StreamingSplits по разделам топика, чтение это снимок потока на момент запроса.

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

Сведём практический вывод. Когда вы пишете федеративный запрос, который трогает таблицы из разных категорий, движок учитывает их разную природу. Большую fact-таблицу из object storage он прочитает множеством параллельных задач. Маленькую dimension-таблицу из PostgreSQL — одним соединением, протолкнув в PostgreSQL фильтр. Это и есть сила федерации: каждый источник используется по своим сильным сторонам, а Trino соединяет результаты.

Понимание категорий помогает и при диагностике. Если запрос медленный, и в нём участвует JDBC-источник, первое подозрение — fact-таблица читается одним split. Если участвует NoSQL без статистики — оптимизатор мог построить плохой план из-за отсутствия данных о кардинальности. Категория источника — это первая гипотеза при разборе проблемного запроса.


Попробуй сам

Откройте список коннекторов в документации Trino (trino.io/docs/current/connector.html) и составьте свою таблицу-карту:

  1. Выпишите 8-10 коннекторов и отнесите каждый к одной из четырёх категорий: object storage, RDBMS, NoSQL/search, streaming.
  2. Для двух коннекторов из категории RDBMS откройте их страницы и найдите раздел про pushdown — сравните, какие виды pushdown поддержаны.
  3. Для одного коннектора object storage (Iceberg) и одного NoSQL (MongoDB) проверьте, упоминается ли поддержка статистики таблиц.
  4. Найдите коннектор Lakehouse и сформулируйте, чем он отличается от четырёх отдельных коннекторов Hive / Iceberg / Delta / Hudi.

Эта карта пригодится в модулях про lakehouse и федерацию — там мы будем разбирать конкретные коннекторы вглубь.


Проверка знанийKnowledge check
Чем категория RDBMS-коннекторов отличается от категории object storage по параллелизму чтения и по pushdown, и как это влияет на выбор источника для fact-таблиц?
ОтветAnswer
Object storage и RDBMS противоположны по этим двум осям. У object storage чтение хорошо параллелится: таблица из множества файлов и row-group превращается в множество splits, и их читают много задач одновременно; статистика для оптимизатора обычно есть (Iceberg, Delta её обновляют). У RDBMS через JDBC параллелизм по умолчанию ограничен — реляционная таблица чаще становится одним split, Trino открывает одно соединение и тянет данные потоком; зато pushdown особенно ценен, потому что у источника есть полноценный SQL-движок, и хорошие JDBC-коннекторы проталкивают в источник predicate, projection, нередко aggregation. Практический вывод: большие fact-таблицы на миллиарды строк лучше держать на object storage, где их прочитают параллельно; реляционные источники стоит подключать ради dimension-таблиц и федерации, где их размер невелик, а pushdown в источник делает запрос эффективным.

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

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Что такое табличный формат (Hive, Iceberg, Delta Lake) и зачем он нужен поверх файлов на object storage?

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

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

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

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