Как без копирования анализировать данные из разных источников в реальном времени с помощью SQL-запросов: каталоги и коннекторы Trino.
Коннекторы Trino: как они работают и что настроить в каталоге
Вчера мы разобрали, как устроен кластер Trino – аналитического движка с массово-параллельной архитектурой (MPP, Massively Parallel Processing), который обрабатывает данные на нескольких серверах без их фактического копирования из внешних источников. Хотя Trino выполняет SQL-операторы над исходными данными, они могут храниться не только в реляционных базах, но и в NoSQL-источниках, включая озера данных и Data LakeHouse, а также потоковые платформы типа Apache Kafka. Чтобы подключиться к источнику данных, Trino использует соответствующие коннекторы. Параметры подключения к источнику данных задаются в конфигурациях коннектора, хранящихся в каталоге.
Каталог Trino — это набор свойств конфигурации для доступа к определенному источнику данных, включая требуемый коннектор, а также учетные данные и URL источника. Каталог определяется в одноименном файле свойств. Например, файл свойств etc/example.properties соответствует каталогу по имени example. Задать учетные данные для подключения к источнику данных в коннекторе можно несколькими способами:
- в файле конфигурации коннектора;
- в отдельном файле свойств;
- в файле хранилища ключей как дополнительные учетные данные, устанавливаемые при подключении к Trino.
Чтобы не хранить конфиденциальные значения в файлах свойств каталога, можно использовать защищенные хранилища секретов, такие как HashiCorp Vault, AWS Secrets Manager, Azure Key Vault или другие подобные решения. Это обеспечивает более высокий уровень безопасности, поскольку секреты хранятся в специализированных системах, доступ к которым контролируется и управляется централизованно. В Trino можно настроить механизм, который будет извлекать эти секреты из защищенного хранилища и использовать их в конфигурации каталога.
Разберем несколько примеров настройки коннектора к разным источникам данных. В частности, чтобы запрашивать PostgreSQL, надо создать файл свойств каталога, который определяет соответствующий коннектор. Для этого следует установить параметру connector.name значение postgresql, а параметру connection-url – значение строки подключения к своей БД, включая драйвер, протокол, сокет и название базы данных, например, jdbc:postgresql://example.net:5432/database. Наконец, надо задать учетные данные для подключения, т.е. connection-user и connection-password. Все это задается в файле etc/catalog/pg_example.properties, что позволяет получить Trino доступ к внешнему источнику как к каталогу pg_example.
Коннектор PostgreSQL может получить доступ только к одной базе данных PostgreSQL. Поэтому для работы с несколькими базами или подключения к нескольким серверам PostgreSQL, придется настроить несколько экземпляров коннектора, добавив еще один каталог, т.е. файл свойств с расширением .properties в директорию etc/catalog.
Аналогичные настройки задаются при подключении к другому источнику данных. Например, чтобы настроить коннектор Redis, надо создать файл свойств каталога etc/catalog/redis_example.properties со следующим содержимым:
connector.name=redis redis.table-names=schema1.table1,schema1.table2 redis.nodes=host:port
Хотя в Redis нет традиционных таблиц, как в реляционных базах данных, Trino использует концепцию таблиц для интеграции с этим key-value хранилищем. Настройка redis.table-names=schema1.table1,schema1.table2 означает, что Trino будет воспринимать определенные наборы данных в Redis как таблицы, которые могут быть сопоставлены с определенными ключами или их паттернами ключей в NoSQL-БД. Каждая пара ключ/значение Redis представляется в виде одной строки в Trino. Строки можно разбить на ячейки с помощью файлов определения таблиц, о чем мы поговорим далее. В настоящее время поддерживаются только ключи Redis строкового и zset-типов, а значения — строкового и хэш-типов. Таким образом, Trino адаптирует традиционные SQL-приемы для аналитики данных, представленных в совершенно другой модели. Еще одним ограничением коннектора Trino к Redis является отсутствие поддержки кластера. Поэтому для работы с несколькими серверами Redis надо задать несколько каталогов, добавив еще один файл свойств с расширением .properties в каталог etc/catalog.
Trino позволяет даже запрашивать как таблицы топики Apache Kafka, используя соответствующий коннектор. Каждое сообщение в топике Kafka будет представлено как строка в Trino. При этом строки будут появляться по мере поступления данных и могут исчезать по мере удаления сегментов, например, при срабатывании политики очистки из-за наступления порогов retention.time или retention.size, заданных при создании топика Kafka. Это может привести к странному поведению при многократном доступе к одной и той же таблице в одном SQL-запросе, например, при выполнении соединения таблицы с самой собой. Для высокой производительности коннектор считывает сообщения из топиков Kafka параллельно несколькими рабочими узлами.
Можно настроить и использовать множество каталогов с разными или одинаковыми коннекторами для доступа к различным источникам данных. Например, если есть два озера данных, можно настроить два каталога в одном кластере Trino, которые оба используют коннектор Hive, чтобы запрашивать данные из обоих Data Lake, даже в рамках одного SQL-запроса. Или можно использовать коннектор Hive для одного каталога озера данных и коннектор Iceberg для другого каталога. Аналогично можно настроить разные каталоги для доступа к разным базам данных.
Помимо параметров подключения к источнику данных, каталог содержит одну или несколько схем, которые содержат таблицы, а также обычные или материализованные представления. При обращении к объектам используется полное имя. Например, полное имя таблицы example.test_data.test ссылается на test таблицу в схеме test_data в каталоге example. Вместе каталог и схема определяют набор таблиц и других объектов, которые можно запросить. При доступе к Hive или реляционной базе данных, схема преобразуется в аналогичную концепцию в целевом хранилище. Другие типы коннекторов могут организовывать таблицы в схемы так, как это реализуется в источнике данных. Например, для документо-ориентированных хранилищ, таких как Elasticsearch, это будет индекс.
Таблица в Trino – это набор неупорядоченных строк, организованных в именованные столбцы с типами данных, как в любой реляционной базе данных. Сопоставление типов из исходных данных в этом MPP-движке определяется коннектором. Поэтому для корректного сопоставления данных из исходного источника и их отображением в Trino надо внимательно смотреть документацию коннектора.
В заключение отметим, что Trino поддерживает множество источников данных, предоставляя готовые коннекторы. Также можно разработать собственный коннектор, написав код на Java, поскольку движок написан на этом языке. После создания нового Maven или Gradle-проекта, надо добавить зависимости для Trino SPI (Service Provider Interface), которые обеспечивают интерфейсы для разработки коннекторов. При этом следует реализовать классы основных компонентов коннектора, которые будут отвечать за управление метаданными, разбиение данных и предоставление записей данных:
- ConnectorFactory — фабрика для создания экземпляров коннектора;
- Connector — основной интерфейс, представляющий коннектор;
- ConnectorMetadata — интерфейс для метаданных;
- ConnectorSplitManager — интерфейс для управления разбивкой данных;
- ConnectorRecordSetProvider или ConnectorPageSourceProvider — интерфейсы для чтения данных.
Как именно это сделать, рассмотрим в другой раз.
Освойте использование Trino на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники