Einführung in Kafka Connectors

Einführung in Kafka-Steckverbinder

1. Überblick

Apache Kafka® ist eine verteilte Streaming-Plattform. In einem früheren Tutorial haben wir diskutiert, wie manimplement Kafka consumers and producers using Spring macht.

In diesem Tutorial erfahren Sie, wie Sie Kafka Connectors verwenden.

Wir werden uns Folgendes ansehen:

  • Verschiedene Arten von Kafka-Steckverbindern

  • Funktionen und Modi von Kafka Connect

  • Konnektorkonfiguration mithilfe von Eigenschaftendateien sowie der REST-API

2. Grundlagen von Kafka Connect und Kafka Connectors

Kafka Connect is a framework for connecting Kafka with external systems wie Datenbanken, Schlüsselwertspeicher, Suchindizes und Dateisysteme unter Verwendung sogenannterConnectors.

Kafka-Steckverbinder sind gebrauchsfertige Komponenten, die uns helfen können Daten aus externen Systemen in Kafka-Themen zu importieren und  export data from Kafka topics into external systems. Wir können vorhandene Connector-Implementierungen für gemeinsame Datenquellen und -senken verwenden oder eigene Connectors implementieren.

Asource connector sammelt Daten von einem System. Quellsysteme können vollständige Datenbanken, Streaming-Tabellen oder Nachrichtenbroker sein. Ein Quellconnector kann auch Metriken von Anwendungsservern in Kafka-Themen erfassen, um die Daten für die Stream-Verarbeitung mit geringer Latenz verfügbar zu machen.

Asink connector liefert Daten aus Kafka-Themen in andere Systeme, z. B. Indizes wie Elasticsearch, Batch-Systeme wie Hadoop oder jede Art von Datenbank.

Einige Konnektoren werden von der Community verwaltet, während andere von Confluent oder seinen Partnern unterstützt werden. Wirklich, wir können Konnektoren für die meisten gängigen Systeme wie S3, JDBC und Cassandra finden, um nur einige zu nennen.

3. Eigenschaften

Zu den Kafka Connect-Funktionen gehören:

  • Ein Framework zum Verbinden externer Systeme mit Kafka -it simplifies the development, deployment, and management of connectors

  • Verteilte und eigenständige Modi -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-Schnittstelle - Wir können Konnektoren mithilfe einer REST-API verwalten

  • Automatisches Offset-Management -Kafka Connect helps us to handle the  * Offset-Festschreibungsprozess *, wodurch wir uns die Mühe ersparen, diesen fehleranfälligen Teil der Connector-Entwicklung manuell zu implementieren

  • Standardmäßig verteilt und skalierbar -Kafka Connect uses the existing group management protocol; we can add more workers to scale up a Kafka Connect cluster

  • Streaming und Batch-Integration - Kafka Connect ist eine ideale Lösung für die Überbrückung von Streaming- und Batch-Datensystemen in Verbindung mit den vorhandenen Funktionen von Kafka

  • Transformationen - diese ermöglichen es uns, einfache und leichte Änderungen an einzelnen Nachrichten vorzunehmen

4. Konfiguration

Anstatt die einfache Kafka-Distribution zu verwenden, laden wir Confluent Platform herunter, eine Kafka-Distribution, die von Confluent, Inc., dem Unternehmen hinter Kafka, bereitgestellt wird. Die Confluent Platform enthält im Vergleich zu normalem Kafka einige zusätzliche Tools und Clients sowie einige zusätzliche vorgefertigte Konnektoren.

Für unseren Fall ist die Open Source Edition ausreichend, die beiConfluent’s site zu finden ist.

5. Schnellstart Kafka Connect

Zunächst werden wir das Prinzip von Kafka Connect,using its most basic Connectors, which are the file source connector and the file sink connector, diskutieren.

Confluent Platform wird zweckmäßigerweise mit diesen beiden Anschlüssen sowie mit Referenzkonfigurationen geliefert.

5.1. Konfiguration des Quellconnectors

Für den Quellanschluss ist die Referenzkonfiguration unter$CONFLUENT_HOME/etc/kafka/connect-file-source.properties verfügbar:

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

Diese Konfiguration verfügt über einige Eigenschaften, die für alle Quellconnectors gelten:

  • name ist ein benutzerdefinierter Name für die Connectorinstanz

  • connector.class gibt die implementierende Klasse an, im Grunde die Art des Connectors

  • tasks.max gibt an, wie viele Instanzen unseres Quellconnectors parallel ausgeführt werden sollen, und

  • topic definiert das Thema, an das der Connector die Ausgabe senden soll

In diesem Fall haben wir auch ein verbinderspezifisches Attribut:

  • file definiert die Datei, aus der der Connector die Eingabe lesen soll

Damit dies dann funktioniert, erstellen wir eine Basisdatei mit einigen Inhalten:

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

Beachten Sie, dass das Arbeitsverzeichnis $ CONFLUENT_HOME ist.

5.2. Sink Connector Konfiguration

Für unseren Spülenanschluss verwenden wir die Referenzkonfiguration bei$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

Logischerweise enthält es genau die gleichen Parameter,though this time connector.class specifies the sink connector implementation, and file is the location where the connector should write the content.

5.3. Arbeiterkonfig

Schließlich müssen wir den Connect-Worker konfigurieren, der die beiden Connectors integriert und das Lesen vom Quellconnector und das Schreiben in den Senkenconnector übernimmt.

Dafür können wir$CONFLUENT_HOME/etc/kafka/connect-standalone.properties verwenden:

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

Beachten Sie, dassplugin.path eine Liste von Pfaden enthalten kann, in denen Connector-Implementierungen verfügbar sind

Da wir mit Kafka gebündelte Konnektoren verwenden, können wirplugin.path auf$CONFLUENT_HOME/share/java setzen. Unter Windows kann es erforderlich sein, hier einen absoluten Pfad anzugeben.

Für die anderen Parameter können wir die Standardwerte belassen:

  • bootstrap.servers enthält die Adressen der Kafka-Broker

  • key.converter undvalue.converter definieren Konverterklassen, die die Daten serialisieren und deserialisieren, wenn sie von der Quelle nach Kafka und dann von Kafka zur Senke fließen

  • key.converter.schemas.enable undvalue.converter.schemas.enable sind konverterspezifische Einstellungen

  • offset.storage.file.filename ist die wichtigste Einstellung, wenn Connect im Standalone-Modus ausgeführt wird: Sie definiert, wo Connect seine Offsetdaten speichern soll

  • offset.flush.interval.ms definiert das Intervall, in dem der Worker versucht, Offsets für Aufgaben festzuschreiben

Die Liste der Parameter ist ziemlich ausgereift. Eine vollständige Liste finden Sie inofficial documentation.

5.4. Kafka Connect im Standalone-Modus

Und damit können wir unser erstes Connector-Setup starten:

$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

Zunächst können wir den Inhalt des Themas über die Befehlszeile überprüfen:

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

Wie wir sehen können, hat der Quellconnector die Daten aus dertest.txt-Datei übernommen, in JSON umgewandelt und an Kafka gesendet:

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

Und wenn wir uns den Ordner$CONFLUENT_HOME ansehen, können wir sehen, dass hier eine Dateitest.sink.txt erstellt wurde:

cat $CONFLUENT_HOME/test.sink.txt
foo
bar

Während der Senken-Connector den Wert aus dem Attributpayload extrahiert und in die Zieldatei schreibt, enthalten die Daten intest.sink.txt den Inhalt der ursprünglichentest.txt -Datei.

Fügen wir nuntest.txt. weitere Zeilen hinzu

Wenn wir dies tun, sehen wir, dass der Quellconnector diese Änderungen automatisch erkennt.

Wir müssen nur sicherstellen, dass am Ende eine neue Zeile eingefügt wird, da sonst der Quellanschluss die letzte Zeile nicht berücksichtigt.

An dieser Stelle stoppen wir den Connect-Prozess, da wir Connect indistributed mode in wenigen Zeilen starten.

6. REST-API von Connect

Bisher haben wir alle Konfigurationen vorgenommen, indem wir Eigenschaftendateien über die Befehlszeile übergeben haben. However, as Connect is designed to run as a service, there is also a REST API available.

Standardmäßig ist es beihttp://localhost:8083 verfügbar. Einige Endpunkte sind:

  • GET /connectors - Gibt eine Liste mit allen verwendeten Konnektoren zurück

  • GET /connectors/{name} - Gibt Details zu einem bestimmten Connector zurück

  • POST /connectors - erstellt einen neuen Konnektor; Der Anforderungshauptteil sollte ein JSON-Objekt sein, das ein Feld für den Zeichenfolgennamen und ein Objektkonfigurationsfeld mit den Connector-Konfigurationsparametern enthält

  • GET /connectors/{name}/status - Gibt den aktuellen Status des Connectors zurück - einschließlich dessen, ob er ausgeführt wird, fehlgeschlagen oder angehalten ist - dem Worker, dem er zugewiesen ist, Fehlerinformationen, wenn er fehlgeschlagen ist, und den Status aller seiner Aufgaben

  • DELETE /connectors/{name} - löscht einen Connector, stoppt ordnungsgemäß alle Aufgaben und löscht seine Konfiguration

  • GET /connector-plugins – gibt eine Liste der im Kafka Connect-Cluster installierten Connector-Plugins zurück

official documentation enthält eine Liste mit allen Endpunkten.

Im folgenden Abschnitt verwenden wir die REST-API zum Erstellen neuer Konnektoren.

7. Kafka Connect im verteilten Modus

Der Standalone-Modus eignet sich perfekt zum Entwickeln und Testen sowie für kleinere Setups. However, if we want to make full use of the distributed nature of Kafka, we have to launch Connect in distributed mode.

Auf diese Weise werden Connectoreinstellungen und Metadaten in Kafka-Themen anstelle des Dateisystems gespeichert. Infolgedessen sind die Arbeitsknoten wirklich zustandslos.

7.1. Connect starten

Eine Referenzkonfiguration für den verteilten Modus finden Sie unter $ CONFLUENT_HOME/etc/kafka/connect-distributed.properties.

Die Parameter sind meistens die gleichen wie im Standalone-Modus. Es gibt nur wenige Unterschiede:

  • group.id definiert den Namen der Connect-Clustergruppe. Der Wert darf nicht mit der ID einer Verbrauchergruppe identisch sein

  • offset.storage.topic,config.storage.topic undstatus.storage.topic definieren Themen für diese Einstellungen. Für jedes Thema können wir auch einen Replikationsfaktor definieren

Auch hier liefertofficial documentation eine Liste mit allen Parametern.

Wir können Connect im verteilten Modus wie folgt starten:

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

7.2. Hinzufügen von Connectors mithilfe der REST-API

Im Vergleich zum eigenständigen Startbefehl haben wir keine Connector-Konfigurationen als Argumente übergeben. Stattdessen müssen wir die Connectors mithilfe der REST-API erstellen.

Um unser Beispiel von früher einzurichten, müssen wir zwei POST-Anforderungen anhttp://localhost:8083/connectors senden, die die folgenden JSON-Strukturen enthalten.

Zuerst müssen wir den Body für den Quell-Connector POST als JSON-Datei erstellen. Hier nennen wir esconnect-file-source.json:

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

Beachten Sie, dass dies der Referenzkonfigurationsdatei, die wir zum ersten Mal verwendet haben, ziemlich ähnlich sieht.

Und dann POSTEN wir es:

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

Dann machen wir dasselbe für den Sink-Connector und rufen die Dateiconnect-file-sink.json auf:

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

Und führen Sie den POST wie zuvor durch:

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

Bei Bedarf können wir überprüfen, ob dieses Setup ordnungsgemäß funktioniert:

$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"}

Und wenn wir uns den Ordner$CONFLUENT_HOME ansehen, können wir sehen, dass hier eine Dateitest-distributed.sink.txt erstellt wurde:

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

Nachdem wir das verteilte Setup getestet haben, bereinigen wir die beiden Anschlüsse:

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

8. Daten transformieren

8.1. Unterstützte Transformationen

Transformationen ermöglichen es uns, einfache und leichte Änderungen an einzelnen Nachrichten vorzunehmen.

Kafka Connect unterstützt die folgenden integrierten Transformationen:

  • InsertField - Fügen Sie ein Feld hinzu, das entweder statische Daten oder Datensatzmetadaten verwendet

  • ReplaceField - Felder filtern oder umbenennen

  • MaskField - Ersetzen Sie ein Feld durch den gültigen Nullwert für den Typ (z. B. Null oder eine leere Zeichenfolge).

  • HoistField - Wickelt das gesamte Ereignis als einzelnes Feld in eine Struktur oder eine Karte ein

  • ExtractField - Extrahiert ein bestimmtes Feld aus struct und map und nimmt nur dieses Feld in die Ergebnisse auf

  • SetSchemaMetadata - Ändern Sie den Schemanamen oder die Version

  • TimestampRouter - Ändern Sie das Thema eines Datensatzes basierend auf dem ursprünglichen Thema und dem Zeitstempel

  • RegexRouter - Ändern Sie das Thema eines Datensatzes basierend auf dem ursprünglichen Thema, einer Ersatzzeichenfolge und einem regulären Ausdruck

Eine Transformation wird mit den folgenden Parametern konfiguriert:

  • transforms - Eine durch Kommas getrennte Liste von Aliasen für die Transformationen

  • transforms.$alias.type - Klassenname für die Transformation

  • transforms.$alias.$transformationSpecificConfig - Konfiguration für die jeweilige Transformation

8.2. Anwenden eines Transformators

Um einige Transformationsfunktionen zu testen, richten Sie die folgenden zwei Transformationen ein:

  • Lassen Sie uns zunächst die gesamte Nachricht als JSON-Struktur umschließen

  • Danach fügen wir dieser Struktur ein Feld hinzu

Bevor wir unsere Transformationen anwenden, müssen wir Connect für die Verwendung von schemenlosem JSON konfigurieren, indem wirconnect-distributed.properties ändern:

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

Danach müssen wir Connect erneut im verteilten Modus starten:

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

Auch hier müssen wir den Body für den Quellconnector POST als JSON-Datei erstellen. Hier nennen wir esconnect-file-source-transform.json.

Neben den bereits bekannten Parametern fügen wir ein paar Zeilen für die beiden erforderlichen Transformationen hinzu:

{
    "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"
    }
}

Führen Sie danach den POST durch:

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

Schreiben wir einige Zeilen in unseretest-transformation.txt:

Foo
Bar

Wenn wir jetzt das Thema vonconnect-transformationuntersuchen, sollten wir die folgenden Zeilen erhalten:

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

9. Ready Connectors verwenden

Nachdem Sie diese einfachen Konnektoren verwendet haben, werfen wir einen Blick auf erweiterte gebrauchsfertige Konnektoren und deren Installation.

9.1. Wo finde ich Steckverbinder?

Vorgefertigte Steckverbinder sind aus verschiedenen Quellen erhältlich:

  • Einige Anschlüsse sind mit Apache Kafka (Quelle und Senke für Dateien und Konsole) gebündelt.

  • Einige weitere Connectors sind in Confluent Platform enthalten (ElasticSearch, HDFS, JDBC und AWS S3).

  • Schauen Sie sich auchConfluent Hub an, eine Art App Store für Kafka-Konnektoren. Die Anzahl der angebotenen Steckverbinder wächst kontinuierlich:

    • Confluent-Konnektoren (entwickelt, getestet, dokumentiert und vollständig von Confluent unterstützt)

    • Zertifizierte Konnektoren (von einem Drittanbieter implementiert und von Confluent zertifiziert)

    • Von der Community entwickelte und unterstützte Anschlüsse

  • Darüber hinaus bietet Confluent auchConnectors Page mit einigen Konnektoren, die auch am Confluent Hub verfügbar sind, aber auch mit einigen weiteren Community-Konnektoren

  • Und schließlich gibt es auch Anbieter, die Steckverbinder als Teil ihres Produkts anbieten. Beispielsweise bietet Landoop eine Streaming-Bibliothek mit dem NamenLenses an, die auch eine Reihe von ~ 25 Open-Source-Konnektoren enthält (von denen viele auch an anderen Stellen aufgelistet sind).

9.2. Installieren von Steckverbindern vom Confluent Hub

Die Enterprise-Version von Confluent enthält ein Skript zum Installieren von Connectors und anderen Komponenten von Confluent Hub (das Skript ist in der Open Source-Version nicht enthalten). Wenn wir die Unternehmensversion verwenden, können wir einen Connector mit dem folgenden Befehl installieren:

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

9.3. Manuelles Installieren von Steckverbindern

Wenn wir einen Connector benötigen, der in Confluent Hub nicht verfügbar ist, oder wenn wir über die Open Source-Version von Confluent verfügen, können wir die erforderlichen Connectors manuell installieren. Dazu müssen wir den Connector herunterladen und entpacken sowie die enthaltenen Bibliotheken in den alsplugin.path. angegebenen Ordner verschieben

Für jeden Connector sollte das Archiv zwei Ordner enthalten, die für uns interessant sind:

  • Der Ordnerlib enthält das Connector-JAR, z. B.kafka-connect-mqtt-1.0.0-preview.jar, sowie einige weitere vom Connector benötigte Jars

  • Der Ordneretcenthält eine oder mehrere Referenzkonfigurationsdateien

Wir müssen den Ordnerlib nach$CONFLUENT_HOME/share/java verschieben oder den Pfad, den wir inconnect-standalone.properties undconnect-distributed.properties alsplugin.path angegeben haben. Dabei kann es auch sinnvoll sein, den Ordner in einen sinnvollen Ordner umzubenennen.

Wir können die Konfigurationsdateien vonetc entweder verwenden, indem wir sie beim Starten im Standalone-Modus referenzieren, oder wir können einfach die Eigenschaften abrufen und daraus eine JSON-Datei erstellen.

10. Fazit

In diesem Tutorial haben wir uns angesehen, wie Kafka Connect installiert und verwendet wird.

Wir haben uns die Arten von Anschlüssen angesehen, sowohl Quelle als auch Senke. Wir haben uns auch einige Funktionen und Modi angesehen, in denen Connect ausgeführt werden kann. Dann haben wir Transformatoren überprüft. Und schließlich haben wir gelernt, wo man bekommt und wie man benutzerdefinierte Konnektoren installiert.

Wie immer befinden sich die Konfigurationsdateien überon GitHub.