Введение в коннекторы Kafka

Введение в коннекторы Kafka

1. обзор

Apache Kafka® - это платформа распределенной потоковой передачи. В предыдущем уроке , мы обсудили, какimplement Kafka consumers and producers using Spring.

В этом руководстве мы узнаем, как использовать коннекторы Kafka.

Мы рассмотрим:

  • Различные типы соединителей Kafka

  • Особенности и режимы Kafka Connect

  • Конфигурация коннекторов с использованием файлов свойств, а также REST API

2. Основы Kafka Connect и Kafka Connectors

Kafka Connect is a framework for connecting Kafka with external systems, такие как базы данных, хранилища значений ключей, поисковые индексы и файловые системы, используя так называемыеConnectors.

Kafka Connectors - это готовые к использованию компоненты, которые могут нам помочь для импорта данных из внешних систем в темы Kafka и  export data from Kafka topics into external systems. Мы можем использовать существующие реализации соединителей для общих источников и приемников данных или реализовать собственные соединители.

Asource connector собирает данные из системы. Исходными системами могут быть целые базы данных, таблицы потоков или брокеры сообщений. Соединитель источника также может собирать метрики с серверов приложений в разделы Kafka, делая данные доступными для потоковой обработки с низкой задержкой.

Asink connector доставляет данные из тем Kafka в другие системы, которые могут быть индексами, такими как Elasticsearch, пакетными системами, такими как Hadoop, или любой базой данных.

Некоторые соединители поддерживаются сообществом, а другие - Confluent или его партнерами. Действительно, мы можем найти соединители для большинства популярных систем, таких как S3, JDBC и Cassandra, и это лишь некоторые из них.

3. Характеристики

Возможности Kafka Connect включают в себя:

  • Фреймворк для подключения внешних систем с Kafka -it simplifies the development, deployment, and management of connectors

  • Распределенный и автономный режимы -it helps us to deploy large clusters by leveraging the distributed nature of Kafka, as well as setups for development, testing, and small production deployments

  • Интерфейс REST - мы можем управлять коннекторами, используя REST API

  • Автоматическое управление смещением - процесс фиксации смещенияKafka Connect helps us to handle the  *, * который избавляет нас от необходимости вручную выполнять эту подверженную ошибкам часть разработки коннектора

  • Распределенный и масштабируемый по умолчанию -Kafka Connect uses the existing group management protocol; we can add more workers to scale up a Kafka Connect cluster

  • Потоковая и пакетная интеграция - Kafka Connect - идеальное решение для объединения потоковых и пакетных систем данных в сочетании с существующими возможностями Kafka.

  • Преобразования - это позволяет нам делать простые и легкие модификации отдельных сообщений

4. Настроить

Вместо использования простого дистрибутива Kafka мы загрузим Confluent Platform, дистрибутив Kafka, предоставленный Confluent, Inc., компанией, стоящей за Kafka. Confluent Platform поставляется с некоторыми дополнительными инструментами и клиентами по сравнению с обычным Kafka, а также с некоторыми дополнительными предварительно созданными коннекторами.

В нашем случае достаточно версии с открытым исходным кодом, которую можно найти по адресуConfluent’s site.

5. Быстрый запуск Kafka Connect

Для начала мы обсудим принцип Kafka Connect,using its most basic Connectors, which are the file source connector and the file sink connector.

Удобно, что Confluent Platform поставляется с обоими этими разъемами, а также с эталонными конфигурациями.

5.1. Конфигурация коннектора источника

Для исходного соединителя эталонная конфигурация доступна в$CONFLUENT_HOME/etc/kafka/connect-file-source.properties:

name=local-file-source
connector.class=FileStreamSource
tasks.max=1
topic=connect-test
file=test.txt

Эта конфигурация имеет некоторые свойства, которые являются общими для всех исходных соединителей:

  • name - это имя, указанное пользователем для экземпляра соединителя.

  • connector.class указывает реализующий класс, в основном тип коннектора

  • tasks.max указывает, сколько экземпляров нашего исходного коннектора должно работать параллельно, и

  • topic определяет тему, в которую соединитель должен отправлять вывод.

В этом случае у нас также есть специальный атрибут коннектора:

  • file определяет файл, из которого коннектор должен читать ввод

Чтобы это сработало, давайте создадим базовый файл с некоторым содержанием:

echo -e "foo\nbar\n" > $CONFLUENT_HOME/test.txt

Обратите внимание, что рабочий каталог - $ CONFLUENT_HOME.

5.2. Конфигурация соединителя раковины

Для нашего соединителя приемника мы будем использовать эталонную конфигурацию в$CONFLUENT_HOME/etc/kafka/connect-file-sink.properties:

name=local-file-sink
connector.class=FileStreamSink
tasks.max=1
file=test.sink.txt
topics=connect-test

Логически он содержит точно такие же параметрыthough this time connector.class specifies the sink connector implementation, and file is the location where the connector should write the content.

5.3. Рабочий Конфиг

Наконец, мы должны сконфигурировать рабочий Connect, который будет интегрировать два наших разъема и выполнять чтение из исходного разъема и запись в приемный разъем.

Для этого мы можем использовать$CONFLUENT_HOME/etc/kafka/connect-standalone.properties:

bootstrap.servers=localhost:9092
key.converter=org.apache.kafka.connect.json.JsonConverter
value.converter=org.apache.kafka.connect.json.JsonConverter
key.converter.schemas.enable=false
value.converter.schemas.enable=false
offset.storage.file.filename=/tmp/connect.offsets
offset.flush.interval.ms=10000
plugin.path=/share/java

Обратите внимание, чтоplugin.path может содержать список путей, по которым доступны реализации коннектора.

Поскольку мы будем использовать коннекторы в комплекте с Kafka, мы можем установитьplugin.path на$CONFLUENT_HOME/share/java. При работе с Windows здесь может потребоваться указать абсолютный путь.

Для других параметров мы можем оставить значения по умолчанию:

  • bootstrap.servers содержит адреса брокеров Kafka

  • key.converter иvalue.converter определяют классы преобразователей, которые сериализуют и десериализуют данные по мере их передачи от источника в Kafka, а затем от Kafka в приемник.

  • key.converter.schemas.enable иvalue.converter.schemas.enable - настройки для конкретного конвертера.

  • offset.storage.file.filename - самый важный параметр при запуске Connect в автономном режиме: он определяет, где Connect должен хранить свои данные смещения.

  • offset.flush.interval.ms определяет интервал, с которым рабочий пытается зафиксировать смещения для задач.

И список параметров довольно зрелый, поэтому посмотритеofficial documentation для полного списка.

5.4. Kafka Connect в автономном режиме

И с этим мы можем начать нашу первую установку соединителя:

$CONFLUENT_HOME/bin/connect-standalone \
  $CONFLUENT_HOME/etc/kafka/connect-standalone.properties \
  $CONFLUENT_HOME/etc/kafka/connect-file-source.properties \
  $CONFLUENT_HOME/etc/kafka/connect-file-sink.properties

Прежде всего, мы можем проверить содержимое темы с помощью командной строки:

$CONFLUENT_HOME/bin/kafka-console-consumer --bootstrap-server localhost:9092 --topic connect-test --from-beginning

Как мы видим, исходный коннектор взял данные из файлаtest.txt, преобразовал их в JSON и отправил в Kafka:

{"schema":{"type":"string","optional":false},"payload":"foo"}
{"schema":{"type":"string","optional":false},"payload":"bar"}

И, если мы посмотрим на папку$CONFLUENT_HOME, мы увидим, что здесь создан файлtest.sink.txt was:

cat $CONFLUENT_HOME/test.sink.txt
foo
bar

Поскольку соединитель приемника извлекает значение из атрибутаpayload и записывает его в целевой файл, данные вtest.sink.txt имеют содержимое исходного s-файлаtest.txt .

Теперь давайте добавим больше строк кtest.txt.

Когда мы это делаем, мы видим, что исходный коннектор обнаруживает эти изменения автоматически.

Нам нужно только вставить новую строку в конец, иначе исходный коннектор не будет учитывать последнюю строку.

На этом этапе давайте остановим процесс Connect, так как мы запустим Connect вdistributed mode в нескольких строках.

6. REST API Connect

До сих пор мы выполняли все конфигурации, передавая файлы свойств через командную строку. However, as Connect is designed to run as a service, there is also a REST API available.с

По умолчанию он доступен вhttp://localhost:8083. Несколько конечных точек:

  • GET /connectors - возвращает список всех используемых коннекторов

  • GET /connectors/{name} - возвращает подробную информацию о конкретном соединителе

  • POST /connectors - создает новый коннектор; тело запроса должно быть объектом JSON, содержащим поле строкового имени и поле конфигурации объекта с параметрами конфигурации коннектора.

  • GET /connectors/{name}/status - возвращает текущий статус коннектора, в том числе, если он запущен, сбой или приостановлен, какому исполнителю он назначен, информацию об ошибке в случае сбоя и состояние всех его задач.

  • DELETE /connectors/{name} - удаляет коннектор, корректно останавливая все задачи и удаляя его конфигурацию

  • GET /connector-plugins –  возвращает список подключаемых модулей коннектора, установленных в кластере Kafka Connect.

official documentation предоставляет список всех конечных точек.

В следующем разделе мы будем использовать REST API для создания новых коннекторов.

7. Kafka Connect в распределенном режиме

Автономный режим отлично подходит для разработки и тестирования, а также для небольших установок. However, if we want to make full use of the distributed nature of Kafka, we have to launch Connect in distributed mode.с

При этом настройки коннектора и метаданные сохраняются в темах Kafka, а не в файловой системе. В результате рабочие узлы действительно не сохраняют состояния.

7.1. Запуск Connect

Эталонную конфигурацию для распределенного режима можно найти в $ CONFLUENT_HOME/etc/kafka/connect-distributed.properties.

Параметры в основном такие же, как для автономного режима. Отличий всего несколько:

  • group.id определяет имя группы кластера Connect. Значение должно отличаться от любого идентификатора группы потребителей

  • offset.storage.topic,config.storage.topic иstatus.storage.topic определяют темы для этих настроек. Для каждой темы мы также можем определить фактор репликации

Опять же,official documentation предоставляет список со всеми параметрами.

Мы можем запустить Connect в распределенном режиме следующим образом:

$CONFLUENT_HOME/bin/connect-distributed $CONFLUENT_HOME/etc/kafka/connect-distributed.properties

7.2. Добавление соединителей с использованием REST API

Теперь, по сравнению с автономной командой запуска, мы не передавали какие-либо конфигурации коннектора в качестве аргументов. Вместо этого мы должны создать соединители, используя REST API.

Чтобы настроить наш предыдущий пример, мы должны отправить два запроса POST наhttp://localhost:8083/connectors, содержащие следующие структуры JSON.

Во-первых, нам нужно создать тело для исходного соединителя POST в виде файла JSON. Здесь мы назовем егоconnect-file-source.json:

{
    "name": "local-file-source",
    "config": {
        "connector.class": "FileStreamSource",
        "tasks.max": 1,
        "file": "test-distributed.txt",
        "topic": "connect-distributed"
    }
}

Обратите внимание, насколько он очень похож на эталонный файл конфигурации, который мы использовали в первый раз.

И тогда мы размещаем это:

curl -d @"$CONFLUENT_HOME/connect-file-source.json" \
  -H "Content-Type: application/json" \
  -X POST http://localhost:8083/connectors

Затем мы сделаем то же самое для соединителя приемника, вызвав файлconnect-file-sink.json:

{
    "name": "local-file-sink",
    "config": {
        "connector.class": "FileStreamSink",
        "tasks.max": 1,
        "file": "test-distributed.sink.txt",
        "topics": "connect-distributed"
    }
}

И выполните POST как раньше:

curl -d @$CONFLUENT_HOME/connect-file-sink.json \
  -H "Content-Type: application/json" \
  -X POST http://localhost:8083/connectors

При необходимости мы можем убедиться, что эта настройка работает правильно:

$CONFLUENT_HOME/bin/kafka-console-consumer --bootstrap-server localhost:9092 --topic connect-distributed --from-beginning
{"schema":{"type":"string","optional":false},"payload":"foo"}
{"schema":{"type":"string","optional":false},"payload":"bar"}

И, если мы посмотрим на папку$CONFLUENT_HOME, мы увидим, что здесь создан файлtest-distributed.sink.txt was:

cat $CONFLUENT_HOME/test-distributed.sink.txt
foo
bar

После того, как мы протестировали распределенную установку, давайте очистим ее, удалив два соединителя:

curl -X DELETE http://localhost:8083/connectors/local-file-source
curl -X DELETE http://localhost:8083/connectors/local-file-sink

8. Преобразование данных

8.1. Поддерживаемые преобразования

Преобразования позволяют нам вносить простые и легкие изменения в отдельные сообщения.

Kafka Connect поддерживает следующие встроенные преобразования:

  • InsertField - Добавить поле, используя либо статические данные, либо метаданные записи

  • ReplaceField - фильтровать или переименовывать поля

  • MaskField - заменить поле допустимым нулевым значением для типа (например, нулем или пустой строкой)

  • HoistField - Обернуть все событие как единое поле внутри структуры или карты

  • ExtractField - извлечь определенное поле из структуры и карты и включить только это поле в результаты

  • SetSchemaMetadata - изменить имя схемы или версию

  • TimestampRouter - изменить тему записи на основе исходной темы и отметки времени

  • RegexRouter - изменить тему записи на основе исходной темы, строки замены и регулярного выражения

Преобразование настраивается с использованием следующих параметров:

  • transforms - разделенный запятыми список псевдонимов для преобразований

  • transforms.$alias.type - Имя класса для преобразования

  • transforms.$alias.$transformationSpecificConfig - Конфигурация для соответствующего преобразования

8.2. Применение трансформатора

Чтобы протестировать некоторые функции преобразования, давайте настроим следующие два преобразования:

  • Во-первых, давайте обернем все сообщение как структуру JSON

  • После этого давайте добавим поле в эту структуру

Перед применением наших преобразований мы должны настроить Connect для использования JSON без схемы, изменивconnect-distributed.properties:

key.converter.schemas.enable=false
value.converter.schemas.enable=false

После этого мы должны перезапустить Connect, снова в распределенном режиме:

$CONFLUENT_HOME/bin/connect-distributed $CONFLUENT_HOME/etc/kafka/connect-distributed.properties

Опять же, нам нужно создать тело для исходного соединителя POST в виде файла JSON. Здесь мы назовем этоconnect-file-source-transform.json.

Помимо уже известных параметров, мы добавим несколько строк для двух необходимых преобразований:

{
    "name": "local-file-source",
    "config": {
        "connector.class": "FileStreamSource",
        "tasks.max": 1,
        "file": "test-transformation.txt",
        "topic": "connect-transformation",
        "transforms": "MakeMap,InsertSource",
        "transforms.MakeMap.type": "org.apache.kafka.connect.transforms.HoistField$Value",
        "transforms.MakeMap.field": "line",
        "transforms.InsertSource.type": "org.apache.kafka.connect.transforms.InsertField$Value",
        "transforms.InsertSource.static.field": "data_source",
        "transforms.InsertSource.static.value": "test-file-source"
    }
}

После этого выполним POST:

curl -d @$CONFLUENT_HOME/connect-file-source-transform.json \
  -H "Content-Type: application/json" \
  -X POST http://localhost:8083/connectors

Напишем несколько строк в нашtest-transformation.txt:

Foo
Bar

Если мы теперь проверим темуconnect-transformation, мы должны получить следующие строки:

{"line":"Foo","data_source":"test-file-source"}
{"line":"Bar","data_source":"test-file-source"}

9. Использование готовых соединителей

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

9.1. Где найти разъемы

Готовые соединители доступны из разных источников:

  • Несколько разъемов в комплекте с простым Apache Kafka (источник и приемник для файлов и консоли)

  • Еще несколько разъемов в комплекте с Confluent Platform (ElasticSearch, HDFS, JDBC и AWS S3)

  • Также проверьтеConfluent Hub, это своего рода магазин приложений для коннекторов Kafka. Количество предлагаемых разъемов постоянно растет:

    • Confluent разъемы (разработаны, протестированы, задокументированы и полностью поддерживаются Confluent)

    • Сертифицированные разъемы (реализованы сторонними разработчиками и сертифицированы Confluent)

    • Разработанные сообществом и поддерживаемые разъемы

  • Помимо этого, Confluent также предоставляетConnectors Page с некоторыми коннекторами, которые также доступны в Confluent Hub, а также с некоторыми другими коннекторами сообщества.

  • И, наконец, есть также поставщики, которые предоставляют соединители как часть своего продукта. Например, Landoop предоставляет потоковую библиотеку под названиемLenses, которая также содержит набор из ~ 25 коннекторов с открытым исходным кодом (многие из них также перечислены в других местах)

9.2. Установка коннекторов из Confluent Hub

Корпоративная версия Confluent предоставляет сценарий для установки соединителей и других компонентов из Confluent Hub (сценарий не включен в версию с открытым исходным кодом). Если мы используем корпоративную версию, мы можем установить коннектор с помощью следующей команды:

$CONFLUENT_HOME/bin/confluent-hub install confluentinc/kafka-connect-mqtt:1.0.0-preview

9.3. Установка разъемов вручную

Если нам нужен соединитель, которого нет в Confluent Hub, или если у нас есть версия Confluent с открытым исходным кодом, мы можем установить необходимые соединители вручную. Для этого нам нужно скачать и разархивировать коннектор, а также переместить включенные библиотеки в папку, указанную какplugin.path..

Для каждого коннектора архив должен содержать две интересующие нас папки:

  • Папкаlib содержит банку соединителя, напримерkafka-connect-mqtt-1.0.0-preview.jar, а также еще несколько банок, необходимых для соединителя.

  • Папкаetc содержит один или несколько эталонных файлов конфигурации.

Нам нужно переместить папкуlib в$CONFLUENT_HOME/share/java или какой бы путь мы ни указали какplugin.path вconnect-standalone.properties иconnect-distributed.properties. При этом, возможно, также имеет смысл переименовать папку во что-нибудь значимое.

Мы можем использовать файлы конфигурации изetc, ссылаясь на них при запуске в автономном режиме, или мы можем просто получить свойства и создать из них файл JSON.

10. Заключение

В этом руководстве мы рассмотрели, как установить и использовать Kafka Connect.

Мы рассмотрели типы разъемов, как источник, так и сток. Мы также рассмотрели некоторые функции и режимы, в которых может работать Connect. Затем мы рассмотрели трансформаторы. И наконец, мы узнали, где взять и как установить кастомные коннекторы.

Как всегда, файлы конфигурации можно найти вon GitHub.