Introdução aos conectores Kafka
1. Visão geral
Apache Kafka® é uma plataforma de streaming distribuída. Em um tutorial anterior , discutimos comoimplement Kafka consumers and producers using Spring.
Neste tutorial, aprenderemos como usar os conectores Kafka.
Vamos dar uma olhada em:
-
Diferentes tipos de conectores Kafka
-
Recursos e modos do Kafka Connect
-
Configuração de conectores usando arquivos de propriedade, bem como a API REST
2. Noções básicas de Kafka Connect e Kafka Connectors
Kafka Connect is a framework for connecting Kafka with external systems, como bancos de dados, armazenamentos de valores-chave, índices de pesquisa e sistemas de arquivos, usando os chamadosConnectors.
Os conectores Kafka são componentes prontos para uso, que podem nos ajudar importar dados de sistemas externos para tópicos do Kafka e export data from Kafka topics into external systems. Podemos usar implementações de conectores existentes para fontes de dados e coletores comuns ou implementar nossos próprios conectores.
Asource connector coleta dados de um sistema. Os sistemas de origem podem ser bancos de dados inteiros, tabelas de fluxos ou intermediários de mensagens. Um conector de origem também pode coletar métricas dos servidores de aplicativos nos tópicos Kafka, disponibilizando os dados para processamento de fluxo com baixa latência.
Asink connector entrega dados de tópicos Kafka para outros sistemas, que podem ser índices como Elasticsearch, sistemas em lote como Hadoop ou qualquer tipo de banco de dados.
Alguns conectores são mantidos pela comunidade, enquanto outros são suportados pelo Confluent ou seus parceiros. Na verdade, podemos encontrar conectores para os sistemas mais populares, como S3, JDBC e Cassandra, apenas para citar alguns.
3. Recursos
Os recursos do Kafka Connect incluem:
-
Uma estrutura para conectar sistemas externos com Kafka -it simplifies the development, deployment, and management of connectors
-
Modos distribuído e autônomo -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 - podemos gerenciar conectores usando uma API REST
-
Gerenciamento automático de deslocamento -Kafka Connect helps us to handle the * processo de confirmação de deslocamento, * que nos poupa o trabalho de implementar manualmente essa parte propensa a erros do desenvolvimento do conector
-
Distribuído e escalonável por padrão -Kafka Connect uses the existing group management protocol; we can add more workers to scale up a Kafka Connect cluster
-
Streaming e integração em lote - Kafka Connect é uma solução ideal para unir sistemas de streaming e dados em lote em conexão com os recursos existentes do Kafka
-
Transformações - isso nos permite fazer modificações simples e leves em mensagens individuais
4. Configuração
Em vez de usar a distribuição Kafka simples, faremos o download do Confluent Platform, uma distribuição Kafka fornecida pela Confluent, Inc., a empresa por trás do Kafka. O Confluent Platform vem com algumas ferramentas e clientes adicionais, em comparação com o Kafka simples, bem como alguns Conectores pré-construídos adicionais.
Para o nosso caso, basta a edição Open Source, que pode ser encontrada emConfluent’s site.
5. Kafka Connect de início rápido
Para começar, discutiremos o princípio do Kafka Connect,using its most basic Connectors, which are the file source connector and the file sink connector.
Convenientemente, o Confluent Platform vem com esses dois conectores, além de configurações de referência.
5.1. Configuração do conector de origem
Para o conector de origem, a configuração de referência está disponível em$CONFLUENT_HOME/etc/kafka/connect-file-source.properties:
name=local-file-source
connector.class=FileStreamSource
tasks.max=1
topic=connect-test
file=test.txt
Essa configuração possui algumas propriedades comuns a todos os conectores de origem:
-
name é um nome especificado pelo usuário para a instância do conector
-
connector.class especifica a classe de implementação, basicamente o tipo de conector
-
tasks.max especifica quantas instâncias de nosso conector de origem devem ser executadas em paralelo, e
-
topic define o tópico para o qual o conector deve enviar a saída
Nesse caso, também temos um atributo específico do conector:
-
file define o arquivo do qual o conector deve ler a entrada
Para que isso funcione, vamos criar um arquivo básico com algum conteúdo:
echo -e "foo\nbar\n" > $CONFLUENT_HOME/test.txt
Observe que o diretório de trabalho é $ CONFLUENT_HOME.
5.2. Configuração do conector coletor
Para nosso conector coletor, usaremos a configuração de referência em$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
Logicamente, ele contém exatamente os mesmos parâmetros,though this time connector.class specifies the sink connector implementation, and file is the location where the connector should write the content.
5.3. Configuração do trabalhador
Por fim, precisamos configurar o trabalhador do Connect, que integrará nossos dois conectores e fará o trabalho de leitura do conector de origem e gravação no conector do coletor.
Para isso, podemos usar$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
Observe queplugin.path pode conter uma lista de caminhos, onde as implementações de conectores estão disponíveis
Como usaremos conectores agrupados com Kafka, podemos definirplugin.path para$CONFLUENT_HOME/share/java. Trabalhando com o Windows, pode ser necessário fornecer um caminho absoluto aqui.
Para os outros parâmetros, podemos deixar os valores padrão:
-
bootstrap.servers contém os endereços dos corretores Kafka
-
key.converter evalue.converter definem classes de conversor, que serializam e desserializam os dados à medida que fluem da fonte para o Kafka e, em seguida, do Kafka para o coletor
-
key.converter.schemas.enable evalue.converter.schemas.enable são configurações específicas do conversor
-
offset.storage.file.filename é a configuração mais importante ao executar o Connect no modo autônomo: ele define onde o Connect deve armazenar seus dados de deslocamento
-
offset.flush.interval.ms define o intervalo em que o trabalhador tenta comprometer deslocamentos para tarefas
E a lista de parâmetros é bastante madura, então verifique oofficial documentation para uma lista completa.
5.4. Kafka Connect em modo autônomo
E com isso, podemos iniciar nossa primeira configuração de conector:
$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
Primeiro, podemos inspecionar o conteúdo do tópico usando a linha de comando:
$CONFLUENT_HOME/bin/kafka-console-consumer --bootstrap-server localhost:9092 --topic connect-test --from-beginning
Como podemos ver, o conector de origem pegou os dados do arquivotest.txt, transformou-os em JSON e os enviou para Kafka:
{"schema":{"type":"string","optional":false},"payload":"foo"}
{"schema":{"type":"string","optional":false},"payload":"bar"}
E, se dermos uma olhada na pasta$CONFLUENT_HOME, podemos ver que um arquivotest.sink.txt foi criado aqui:
cat $CONFLUENT_HOME/test.sink.txt
foo
bar
Como o conector coletor extrai o valor do atributopayload e o grava no arquivo de destino, os dados emtest.sink.txt têm o conteúdo do arquivotest.txt original.
Agora vamos adicionar mais linhas atest.txt.
Quando o fazemos, vemos que o conector de origem detecta essas alterações automaticamente.
Só precisamos ter certeza de inserir uma nova linha no final, caso contrário, o conector de origem não considerará a última linha.
Neste ponto, vamos parar o processo de conexão, pois vamos iniciar a conexão emdistributed mode em algumas linhas.
6. API REST do Connect
Até agora, fizemos todas as configurações passando arquivos de propriedades pela linha de comando. However, as Connect is designed to run as a service, there is also a REST API available.
Por padrão, está disponível emhttp://localhost:8083. Alguns pontos finais são:
-
GET /connectors - retorna uma lista com todos os conectores em uso
-
GET /connectors/{name} - retorna detalhes sobre um conector específico
-
POST /connectors - cria um novo conector; o corpo da solicitação deve ser um objeto JSON contendo um campo de nome de string e um campo de configuração de objeto com os parâmetros de configuração do conector
-
GET /connectors/{name}/status - retorna o status atual do conector - incluindo se está em execução, falhou ou pausou - a qual trabalhador está atribuído, informações de erro se falhou e o estado de todas as suas tarefas
-
DELETE /connectors/{name} - exclui um conector, interrompendo normalmente todas as tarefas e excluindo sua configuração
-
GET /connector-plugins – retorna uma lista de plug-ins de conectores instalados no cluster Kafka Connect
Oofficial documentation fornece uma lista com todos os terminais.
Usaremos a API REST para criar novos conectores na seção a seguir.
7. Kafka Connect em modo distribuído
O modo autônomo funciona perfeitamente para desenvolvimento e teste, além de configurações menores. However, if we want to make full use of the distributed nature of Kafka, we have to launch Connect in distributed mode.
Ao fazer isso, as configurações e os metadados do conector são armazenados nos tópicos do Kafka, em vez do sistema de arquivos. Como resultado, os nós dos trabalhadores são realmente sem estado.
7.1. Iniciando a conexão
Uma configuração de referência para o modo distribuído pode ser encontrada em $ CONFLUENT_HOME/etc/kafka/connect-distributed.properties.
Os parâmetros são basicamente os mesmos do modo autônomo. Existem apenas algumas diferenças:
-
group.id define o nome do grupo de clusters do Connect. O valor deve ser diferente de qualquer ID de grupo de consumidores
-
offset.storage.topic,config.storage.topic estatus.storage.topic definem tópicos para essas configurações. Para cada tópico, também podemos definir um fator de replicação
Novamente, oofficial documentation fornece uma lista com todos os parâmetros.
Podemos iniciar o Connect no modo distribuído da seguinte maneira:
$CONFLUENT_HOME/bin/connect-distributed $CONFLUENT_HOME/etc/kafka/connect-distributed.properties
7.2. Adicionando conectores usando a API REST
Agora, em comparação com o comando de inicialização autônomo, não passamos nenhuma configuração de conector como argumento. Em vez disso, precisamos criar os conectores usando a API REST.
Para configurar nosso exemplo anterior, temos que enviar duas solicitações POST parahttp://localhost:8083/connectors contendo as seguintes estruturas JSON.
Primeiro, precisamos criar o corpo para o conector de origem POST como um arquivo JSON. Aqui, vamos chamá-lo deconnect-file-source.json:
{
"name": "local-file-source",
"config": {
"connector.class": "FileStreamSource",
"tasks.max": 1,
"file": "test-distributed.txt",
"topic": "connect-distributed"
}
}
Observe como isso se parece muito com o arquivo de configuração de referência que usamos pela primeira vez.
E depois postamos:
curl -d @"$CONFLUENT_HOME/connect-file-source.json" \
-H "Content-Type: application/json" \
-X POST http://localhost:8083/connectors
Em seguida, faremos o mesmo para o conector do coletor, chamando o arquivoconnect-file-sink.json:
{
"name": "local-file-sink",
"config": {
"connector.class": "FileStreamSink",
"tasks.max": 1,
"file": "test-distributed.sink.txt",
"topics": "connect-distributed"
}
}
E execute o POST como antes:
curl -d @$CONFLUENT_HOME/connect-file-sink.json \
-H "Content-Type: application/json" \
-X POST http://localhost:8083/connectors
Se necessário, podemos verificar se esta configuração está funcionando corretamente:
$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"}
E, se dermos uma olhada na pasta$CONFLUENT_HOME, podemos ver que um arquivotest-distributed.sink.txt foi criado aqui:
cat $CONFLUENT_HOME/test-distributed.sink.txt
foo
bar
Depois de testar a configuração distribuída, vamos limpar, removendo os dois conectores:
curl -X DELETE http://localhost:8083/connectors/local-file-source
curl -X DELETE http://localhost:8083/connectors/local-file-sink
8. Transformando dados
8.1. Transformações suportadas
As transformações nos permitem fazer modificações simples e leves em mensagens individuais.
O Kafka Connect suporta as seguintes transformações internas:
-
InsertField - Adicionar um campo usando dados estáticos ou metadados de registro
-
ReplaceField - Filtrar ou renomear campos
-
MaskField - Substitua um campo pelo valor nulo válido para o tipo (zero ou uma string vazia, por exemplo)
-
HoistField - Envolve todo o evento como um único campo dentro de uma estrutura ou mapa
-
ExtractField - Extraia um campo específico de struct e map e inclua apenas este campo nos resultados
-
SetSchemaMetadata - Modifique o nome ou versão do esquema
-
TimestampRouter - Modifique o tópico de um registro com base no tópico original e no carimbo de data / hora
-
RegexRouter - Modifica o tópico de um registro com base no tópico original, uma string de substituição e uma expressão regular
Uma transformação é configurada usando os seguintes parâmetros:
-
transforms - uma lista separada por vírgulas de aliases para as transformações
-
transforms.$alias.type - nome da classe para a transformação
-
transforms.$alias.$transformationSpecificConfig - Configuração para a respectiva transformação
8.2. Aplicando um transformador
Para testar alguns recursos de transformação, vamos configurar as duas transformações a seguir:
-
Primeiro, vamos embrulhar a mensagem inteira como uma estrutura JSON
-
Depois disso, vamos adicionar um campo a essa estrutura
Antes de aplicar nossas transformações, temos que configurar o Connect para usar JSON sem esquema, modificando oconnect-distributed.properties:
key.converter.schemas.enable=false
value.converter.schemas.enable=false
Depois disso, precisamos reiniciar o Connect, novamente no modo distribuído:
$CONFLUENT_HOME/bin/connect-distributed $CONFLUENT_HOME/etc/kafka/connect-distributed.properties
Novamente, precisamos criar o corpo para o conector de origem POST como um arquivo JSON. Aqui, vamos chamá-lo deconnect-file-source-transform.json.
Além dos parâmetros já conhecidos, adicionamos algumas linhas para as duas transformações necessárias:
{
"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"
}
}
Depois disso, vamos realizar o POST:
curl -d @$CONFLUENT_HOME/connect-file-source-transform.json \
-H "Content-Type: application/json" \
-X POST http://localhost:8083/connectors
Vamos escrever algumas linhas em nossotest-transformation.txt:
Foo
Bar
Se agora inspecionarmos o tópicoconnect-transformation, devemos obter as seguintes linhas:
{"line":"Foo","data_source":"test-file-source"}
{"line":"Bar","data_source":"test-file-source"}
9. Usando conectores prontos
Depois de usar esses conectores simples, vamos dar uma olhada em conectores prontos para usar mais avançados e como instalá-los.
9.1. Onde encontrar conectores
Conectores pré-construídos estão disponíveis em diferentes fontes:
-
Alguns conectores são fornecidos com o Apache Kafka simples (origem e coletor de arquivos e console)
-
Mais alguns conectores são fornecidos com a Confluent Platform (ElasticSearch, HDFS, JDBC e AWS S3)
-
Verifique tambémConfluent Hub, que é uma espécie de app store para conectores Kafka. O número de conectores oferecidos está crescendo continuamente:
-
Conectores Confluent (desenvolvidos, testados, documentados e são totalmente suportados pelo Confluent)
-
Conectores certificados (implementados por terceiros e certificados pela Confluent)
-
Conectores desenvolvidos e suportados pela comunidade
-
-
Além disso, o Confluent também fornece umConnectors Page, com alguns conectores que também estão disponíveis no Confluent Hub, mas também com mais alguns conectores da comunidade
-
E, finalmente, também existem fornecedores que fornecem conectores como parte de seu produto. Por exemplo, Landoop fornece uma biblioteca de streaming chamadaLenses, que também contém um conjunto de cerca de 25 conectores de código aberto (muitos deles também listados em outros lugares)
9.2. Instalando Conectores do Confluent Hub
A versão corporativa do Confluent fornece um script para a instalação de conectores e outros componentes do Confluent Hub (o script não está incluído na versão de código-fonte aberto). Se estivermos usando a versão corporativa, podemos instalar um conector usando o seguinte comando:
$CONFLUENT_HOME/bin/confluent-hub install confluentinc/kafka-connect-mqtt:1.0.0-preview
9.3. Instalando Conectores Manualmente
Se precisarmos de um conector, que não está disponível no Confluent Hub, ou se tivermos a versão Open Source do Confluent, podemos instalar os conectores necessários manualmente. Para isso, temos que baixar e descompactar o conector, bem como mover as bibliotecas incluídas para a pasta especificada comoplugin.path.
Para cada conector, o arquivo deve conter duas pastas que são interessantes para nós:
-
A pastalib contém o jar do conector, por exemplo,kafka-connect-mqtt-1.0.0-preview.jar, bem como mais alguns jarros exigidos pelo conector
-
A pastaetc contém um ou mais arquivos de configuração de referência
Temos que mover a pastalib para$CONFLUENT_HOME/share/java, ou qualquer caminho que especificamos comoplugin.path emconnect-standalone.propertieseconnect-distributed.properties. Ao fazer isso, também pode fazer sentido renomear a pasta para algo significativo.
Podemos usar os arquivos de configuração deetc referenciando-os ao iniciar no modo autônomo ou podemos apenas pegar as propriedades e criar um arquivo JSON a partir delas.
10. Conclusão
Neste tutorial, vimos como instalar e usar o Kafka Connect.
Observamos os tipos de conectores, tanto de origem quanto de dissipador. Também examinamos alguns recursos e modos nos quais o Connect pode ser executado. Em seguida, revisamos os transformadores. E, finalmente, aprendemos onde obter e como instalar conectores personalizados.
Como sempre, os arquivos de configuração podem ser encontrados emon GitHub.