Introduction aux connecteurs Kafka

Introduction aux connecteurs Kafka

1. Vue d'ensemble

Apache Kafka® est une plateforme de streaming distribuée. Dans un tutoriel précédent , nous avons discuté de la façon deimplement Kafka consumers and producers using Spring.

Dans ce didacticiel, nous allons apprendre à utiliser les connecteurs Kafka.

Nous allons examiner:

  • Différents types de connecteurs Kafka

  • Caractéristiques et modes de Kafka Connect

  • Configuration des connecteurs à l'aide de fichiers de propriétés ainsi que de l'API REST

2. Principes de base de Kafka Connect et des connecteurs Kafka

Kafka Connect is a framework for connecting Kafka with external systems tels que les bases de données, les magasins de valeurs-clés, les index de recherche et les systèmes de fichiers, en utilisant ce que l'on appelle lesConnectors.

Les connecteurs Kafka sont des composants prêts à l'emploi, qui peuvent nous aider pour importer des données de systèmes externes dans des rubriques Kafka et  export data from Kafka topics into external systems. Nous pouvons utiliser les implémentations de connecteurs existantes pour les sources et les puits de données courants ou implémenter nos propres connecteurs.

Unsource connector collecte les données d'un système. Les systèmes sources peuvent être des bases de données entières, des tables de flux ou des courtiers de messages. Un connecteur source pourrait également collecter des métriques des serveurs d'applications dans les rubriques Kafka, rendant ainsi les données disponibles pour le traitement de flux avec une faible latence.

Unsink connector fournit des données à partir de sujets Kafka dans d'autres systèmes, qui peuvent être des index tels qu'Elasticsearch, des systèmes de traitement par lots tels que Hadoop ou tout type de base de données.

Certains connecteurs sont maintenus par la communauté, tandis que d'autres sont pris en charge par Confluent ou ses partenaires. Vraiment, nous pouvons trouver des connecteurs pour les systèmes les plus populaires, comme S3, JDBC et Cassandra, pour n'en nommer que quelques-uns.

3. Caractéristiques

Les fonctionnalités de Kafka Connect comprennent:

  • Un cadre pour connecter des systèmes externes avec Kafka -it simplifies the development, deployment, and management of connectors

  • Modes distribués et autonomes -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

  • Interface REST - nous pouvons gérer les connecteurs à l'aide d'une API REST

  • Gestion automatique des décalages -Kafka Connect helps us to handle the  * processus de validation de décalage, * qui nous évite d'avoir à implémenter manuellement cette partie sujette aux erreurs du développement de connecteurs

  • Distribué et évolutif par défaut -Kafka Connect uses the existing group management protocol; we can add more workers to scale up a Kafka Connect cluster

  • Streaming et intégration par lots - Kafka Connect est une solution idéale pour relier les systèmes de streaming et de données par lots en relation avec les capacités existantes de Kafka

  • Transformations - Elles nous permettent d’apporter des modifications simples et légères à des messages individuels.

4. Installer

Au lieu d'utiliser la distribution Kafka ordinaire, nous téléchargerons Confluent Platform, une distribution Kafka fournie par Confluent, Inc., la société derrière Kafka. Confluent Platform est livré avec des outils et des clients supplémentaires, par rapport à Kafka ordinaire, ainsi que des connecteurs préconstruits supplémentaires.

Pour notre cas, l'édition Open Source est suffisante, qui peut être trouvée àConfluent’s site.

5. Démarrage rapide de Kafka Connect

Pour commencer, nous allons discuter du principe de Kafka Connect,using its most basic Connectors, which are the file source connector and the file sink connector.

De manière pratique, Confluent Platform est fourni avec ces deux connecteurs, ainsi que des configurations de référence.

5.1. Configuration du connecteur source

Pour le connecteur source, la configuration de référence est disponible à$CONFLUENT_HOME/etc/kafka/connect-file-source.properties:

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

Cette configuration a certaines propriétés communes à tous les connecteurs source:

  • name est un nom spécifié par l'utilisateur pour l'instance de connecteur

  • connector.class spécifie la classe d'implémentation, essentiellement le type de connecteur

  • tasks.max spécifie combien d'instances de notre connecteur source doivent s'exécuter en parallèle, et

  • topic définit le sujet auquel le connecteur doit envoyer la sortie

Dans ce cas, nous avons également un attribut spécifique au connecteur:

  • file définit le fichier à partir duquel le connecteur doit lire l'entrée

Pour que cela fonctionne, créons un fichier de base avec du contenu:

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

Notez que le répertoire de travail est $ CONFLUENT_HOME.

5.2. Configuration du connecteur d'évier

Pour notre connecteur récepteur, nous utiliserons la configuration de référence à$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

Logiquement, il contient exactement les mêmes paramètres,though this time connector.class specifies the sink connector implementation, and file is the location where the connector should write the content.

5.3. Travailleur Config

Enfin, nous devons configurer le travailleur Connect, qui intégrera nos deux connecteurs et effectuera le travail de lecture à partir du connecteur source et d’écriture sur le connecteur du récepteur.

Pour cela, nous pouvons utiliser$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

Notez queplugin.path peut contenir une liste de chemins, où les implémentations de connecteur sont disponibles

Comme nous utiliserons des connecteurs fournis avec Kafka, nous pouvons définirplugin.path sur$CONFLUENT_HOME/share/java. Sous Windows, il peut être nécessaire de fournir un chemin absolu ici.

Pour les autres paramètres, on peut laisser les valeurs par défaut:

  • bootstrap.servers contient les adresses des courtiers Kafka

  • key.converter etvalue.converter définissent des classes de convertisseur, qui sérialisent et désérialisent les données à mesure qu'elles circulent de la source vers Kafka, puis de Kafka vers le puits

  • key.converter.schemas.enable etvalue.converter.schemas.enable sont des paramètres spécifiques au convertisseur

  • offset.storage.file.filename est le paramètre le plus important lors de l'exécution de Connect en mode autonome: il définit où Connect doit stocker ses données de décalage

  • offset.flush.interval.ms définit l'intervalle auquel le travailleur essaie de valider les décalages pour les tâches

Et la liste des paramètres est assez mature, alors consultez lesofficial documentation pour une liste complète.

5.4. Kafka Connect en mode autonome

Et avec cela, nous pouvons commencer notre première configuration de connecteur:

$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

Tout d'abord, nous pouvons inspecter le contenu du sujet en utilisant la ligne de commande:

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

Comme nous pouvons le voir, le connecteur source a pris les données du fichiertest.txt, les a transformées en JSON et les a envoyées à Kafka:

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

Et, si nous regardons le dossier$CONFLUENT_HOME, nous pouvons voir qu'un fichiertest.sink.txt was créé ici:

cat $CONFLUENT_HOME/test.sink.txt
foo
bar

Lorsque le connecteur récepteur extrait la valeur de l'attributpayload et l'écrit dans le fichier de destination, les données detest.sink.txt ont le contenu du fichiertest.txt d'origine.

Ajoutons maintenant plus de lignes àtest.txt.

Lorsque nous le faisons, nous voyons que le connecteur source détecte ces modifications automatiquement.

Nous devons simplement nous assurer d'insérer une nouvelle ligne à la fin, sinon le connecteur source ne prendra pas en compte la dernière ligne.

À ce stade, arrêtons le processus de connexion, car nous allons démarrer Connect dansdistributed mode en quelques lignes.

6. API REST de Connect

Jusqu'à présent, nous faisions toutes les configurations en passant des fichiers de propriétés via la ligne de commande. However, as Connect is designed to run as a service, there is also a REST API available.

Par défaut, il est disponible àhttp://localhost:8083. Quelques points finaux sont:

  • GET /connectors - retourne une liste avec tous les connecteurs utilisés

  • GET /connectors/{name} - renvoie des détails sur un connecteur spécifique

  • POST /connectors - crée un nouveau connecteur; le corps de la requête doit être un objet JSON contenant un champ de nom de chaîne et un champ de configuration d'objet avec les paramètres de configuration du connecteur

  • GET /connectors/{name}/status - renvoie l'état actuel du connecteur - y compris s'il est en cours d'exécution, en échec ou en pause - à quel worker il est affecté, des informations d'erreur s'il a échoué et l'état de toutes ses tâches

  • DELETE /connectors/{name} - supprime un connecteur, arrête toutes les tâches en douceur et supprime sa configuration

  • GET /connector-plugins –  renvoie une liste des plugins de connecteur installés dans le cluster Kafka Connect

Leofficial documentation fournit une liste de tous les points de terminaison.

Nous utiliserons l'API REST pour créer de nouveaux connecteurs dans la section suivante.

7. Kafka Connect en mode distribué

Le mode autonome fonctionne parfaitement pour le développement et les tests, ainsi que pour les configurations plus petites. However, if we want to make full use of the distributed nature of Kafka, we have to launch Connect in distributed mode.

Ainsi, les paramètres de connecteur et les métadonnées sont stockés dans les rubriques Kafka au lieu du système de fichiers. En conséquence, les nœuds de travail sont vraiment sans état.

7.1. Démarrer Connect

Une configuration de référence pour le mode distribué peut être trouvée dans $ CONFLUENT_HOME/etc/kafka/connect-distributed.properties.

Les paramètres sont généralement les mêmes que pour le mode autonome. Il n'y a que quelques différences:

  • group.id définit le nom du groupe de cluster Connect. La valeur doit être différente de tout ID de groupe de consommateurs

  • offset.storage.topic,config.storage.topic etstatus.storage.topic définissent les sujets pour ces paramètres. Pour chaque sujet, nous pouvons également définir un facteur de réplication

Encore une fois, leofficial documentation fournit une liste avec tous les paramètres.

Nous pouvons démarrer Connect en mode distribué comme suit:

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

7.2. Ajout de connecteurs à l'aide de l'API REST

Désormais, par rapport à la commande de démarrage autonome, nous n'avons transmis aucune configuration de connecteur en tant qu'arguments. Au lieu de cela, nous devons créer les connecteurs à l'aide de l'API REST.

Pour configurer notre exemple précédent, nous devons envoyer deux requêtes POST àhttp://localhost:8083/connectors contenant les structures JSON suivantes.

Premièrement, nous devons créer le corps du connecteur source POST sous forme de fichier JSON. Ici, nous l'appelleronsconnect-file-source.json:

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

Notez à quel point cela ressemble assez au fichier de configuration de référence que nous avons utilisé la première fois.

Et puis nous postons:

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

Ensuite, nous ferons de même pour le connecteur récepteur, en appelant le fichierconnect-file-sink.json:

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

Et effectuez le POST comme avant:

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

Si nécessaire, nous pouvons vérifier que cette configuration fonctionne correctement:

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

Et, si nous regardons le dossier$CONFLUENT_HOME, nous pouvons voir qu'un fichiertest-distributed.sink.txt was créé ici:

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

Après avoir testé la configuration distribuée, faisons le ménage en supprimant les deux connecteurs:

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

8. Transformer les données

8.1. Transformations prises en charge

Les transformations nous permettent d’apporter des modifications simples et légères à des messages individuels.

Kafka Connect prend en charge les transformations intégrées suivantes:

  • InsertField - Ajout d'un champ en utilisant des données statiques ou des métadonnées d'enregistrement

  • ReplaceField - Filtrer ou renommer les champs

  • MaskField - Remplace un champ par la valeur nulle valide pour le type (zéro ou une chaîne vide, par exemple)

  • HoistField - Enveloppe l'événement entier comme un seul champ dans une structure ou une carte

  • ExtractField - Extrait un champ spécifique de struct et map et n'inclut que ce champ dans les résultats

  • SetSchemaMetadata - Modifier le nom ou la version du schéma

  • TimestampRouter - Modifier le sujet d'un enregistrement en fonction du sujet d'origine et de l'horodatage

  • RegexRouter - Modifie le sujet d'un enregistrement en fonction du sujet d'origine, d'une chaîne de remplacement et d'une expression régulière

Une transformation est configurée à l'aide des paramètres suivants:

  • transforms - Une liste d'alias séparés par des virgules pour les transformations

  • transforms.$alias.type - Nom de classe pour la transformation

  • transforms.$alias.$transformationSpecificConfig - Configuration pour la transformation respective

8.2. Appliquer un transformateur

Pour tester certaines fonctionnalités de transformation, configurons les deux transformations suivantes:

  • Tout d'abord, enveloppons l'intégralité du message sous forme de structure JSON

  • Après cela, ajoutons un champ à cette structure

Avant d'appliquer nos transformations, nous devons configurer Connect pour utiliser le JSON sans schéma, en modifiant lesconnect-distributed.properties:

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

Après cela, nous devons redémarrer Connect, toujours en mode distribué:

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

De nouveau, nous devons créer le corps du POST du connecteur source sous forme de fichier JSON. Ici, nous l'appelleronsconnect-file-source-transform.json.

Outre les paramètres déjà connus, nous ajoutons quelques lignes pour les deux transformations requises:

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

Après cela, effectuons le POST:

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

Écrivons quelques lignes dans nostest-transformation.txt:

Foo
Bar

Si nous inspectons maintenant la rubriqueconnect-transformation, nous devrions obtenir les lignes suivantes:

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

9. Utilisation de connecteurs prêts

Après avoir utilisé ces connecteurs simples, examinons des connecteurs prêts à l'emploi plus avancés et comment les installer.

9.1. Où trouver des connecteurs

Les connecteurs pré-construits sont disponibles à partir de différentes sources:

  • Quelques connecteurs sont fournis avec Apache Kafka (source et collecteur pour les fichiers et la console)

  • Certains autres connecteurs sont fournis avec Confluent Platform (ElasticSearch, HDFS, JDBC et AWS S3).

  • Consultez égalementConfluent Hub, qui est une sorte de magasin d'applications pour les connecteurs Kafka. Le nombre de connecteurs proposés augmente sans cesse:

    • Connecteurs Confluent (développés, testés, documentés et entièrement pris en charge par Confluent)

    • Connecteurs certifiés (mis en œuvre par une tierce partie et certifiés par Confluent)

    • Connecteurs développés et supportés par la communauté

  • Au-delà de cela, Confluent fournit également unConnectors Page, avec quelques connecteurs qui sont également disponibles sur le Confluent Hub, mais aussi avec d'autres connecteurs de communauté

  • Enfin, certains fournisseurs proposent des connecteurs dans leur produit. Par exemple, Landoop fournit une bibliothèque de diffusion en continu appeléeLenses, qui contient également un ensemble d'environ 25 connecteurs open source (dont beaucoup sont également répertoriés à d'autres endroits)

9.2. Installer des connecteurs depuis Confluent Hub

La version d'entreprise de Confluent fournit un script pour l'installation de Connectors et d'autres composants à partir de Confluent Hub (le script n'est pas inclus dans la version Open Source). Si nous utilisons la version entreprise, nous pouvons installer un connecteur à l'aide de la commande suivante:

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

9.3. Installation manuelle des connecteurs

Si nous avons besoin d’un connecteur qui n’est pas disponible sur Confluent Hub ou si nous avons la version Open Source de Confluent, nous pouvons installer les connecteurs requis manuellement. Pour cela, nous devons télécharger et décompresser le connecteur, ainsi que déplacer les bibliothèques incluses dans le dossier spécifié commeplugin.path.

Pour chaque connecteur, l'archive doit contenir deux dossiers qui nous intéressent:

  • Le dossierlib contient le fichier jar du connecteur, par exemplekafka-connect-mqtt-1.0.0-preview.jar, ainsi que quelques autres fichiers jar requis par le connecteur

  • Le dossieretc contient un ou plusieurs fichiers de configuration de référence

Nous devons déplacer le dossierlib vers$CONFLUENT_HOME/share/java, ou le chemin que nous avons spécifié commeplugin.path dansconnect-standalone.properties etconnect-distributed.properties. Ce faisant, il peut également être judicieux de renommer le dossier en quelque chose de significatif.

Nous pouvons utiliser les fichiers de configuration deetc soit en les référençant en démarrant en mode autonome, soit nous pouvons simplement récupérer les propriétés et créer un fichier JSON à partir d'elles.

10. Conclusion

Dans ce didacticiel, nous avons examiné comment installer et utiliser Kafka Connect.

Nous avons examiné les types de connecteurs, à la fois source et récepteur. Nous avons également examiné certaines fonctionnalités et modes dans lesquels Connect peut s'exécuter. Ensuite, nous avons passé en revue les transformateurs. Et enfin, nous avons appris où trouver et comment installer des connecteurs personnalisés.

Comme toujours, les fichiers de configuration peuvent être trouvés suron GitHub.