Debezium, Kafka e .Net Core

Fernando Mendes
JunDevelopers
Published in
7 min readSep 3, 2020

Olá Pessoal, tudo bem?

Hoje em dia é notório o crescimento de aplicações distribuídas, microserviços para solucionar problemas de negócio para uma empresa.

No início dos anos 2000, tínhamos somente uma aplicação que fazia tudo, o famoso monólito e era muito difícil ou quase impossível, escalar essa aplicação em servidores que ficavam hospedados nos data centers na sede da empresa.

Os ambientes de nuvem cresceram de forma exponencial, e também o conceito de separação de contextos vem fazendo nós arquitetos, desenvolvedores, a criar soluções sempre mais rápidas e com baixo acoplamento.

Para isso precisamos separar banco de dados, para que cada banco tenham informações específicas de cada contexto, e precisamos ter de certa forma, uma sincronização desses dados em vários outros bancos de dados. Como por exemplo:

Esse exemplo, de forma simples, mostra que ao cadastrar um novo funcionário, a informação do funcionário pode estar em outros sistemas. Cada sistema(caixinha) tem seu banco de dados.

Como vamos ter a mesma informação nos outros 3 bancos de dados?

Podemos fazer isso com mensageria, colocando o RabbitMQ para orquestrar tudo isso. Onde cada sistema recebe uma mensagem com o dado do funcionário para ser processado.

É uma ótima abordagem, e funciona muito bem, mas caso os consumidores possam dar problemas, como por exemplo um deles tentou conectar na base, e a mesma está fora, as mensagens não serão processadas, causando assim diferenças de informações, entre os consumidores;

Para resolver esse problema, vamos utilizar o Kafka Connect.

O Kafka Connect é um serviço que não funciona sozinho, temos que instalar plugins de conexão com as bases de dados. Neste exemplo vamos usar como plugin para monitorar o banco de dados (Source) o Debezium.

O que é o Debezium?

Debezium é um conjunto de serviços distribuídos para capturar mudanças em seus bancos de dados para que seus aplicativos possam ver essas mudanças e responder a elas.

O Debezium registra todas as alterações de nível de linha em cada tabela de banco de dados em um fluxo de eventos de mudança e os aplicativos simplesmente leem esses fluxos para ver os eventos de mudança na mesma ordem em que ocorreram.

De acordo com a documentação o Debezium, consegue capturar as mudanças como Insert, Delete, Update de meu banco de dados e criar um tópico no Kafka, para que uma outra aplicação consuma.

Mas para o funcionamento do Debezium, o SQL Server necessita que se habilite a funcionalidade Change Data Capture(CDC)

Os registros do Change Data Capture inserem, atualizam e excluem atividades aplicadas a uma tabela do SQL Server . Ele também disponibiliza os detalhes das mudanças em um formato relacional facilmente utilizável. As informações de coluna e os metadados exigidos para a aplicação de alterações em um ambiente de destino são capturados para as linhas modificadas e armazenados nas tabelas de alteração que espelham a estrutura da coluna das tabelas de origem rastreadas. As funções avaliadas da tabela são fornecidas para permitir acesso sistemático aos dados de alteração pelos consumidores

O Debezium tem vários outros conectores para os principais banco de dados como Mongo, Oracle, MySql e entre outros.

Para nosso exemplo, vamos usar o SQL Server, e uma aplicação consumidora dos tópicos do Kafka.

Vamos lá, inicialmente antes de tudo, vamos criar uma instância do SQL Server. Vou criar o banco de dados via container Docker:

docker run -e ACCEPT_EULA=Y -e SA_PASSWORD=[suasenha] -e MSSQL_PID=Developer -p 1433:1433 -e MSSQL_AGENT_ENABLED=true -d mcr.microsoft.com/mssql/server:2019-latest

Para a utilização do Debezium no SQL Server, teremos que habilitar o Agent do SQL Server. Pois o Agent monitorá as alterações feitas pelo banco de dados e assim o Debezium irá capturar os dados à serem enviados ao Kafka. Por isso da variável -e MSSQL_AGENT_ENABLED=true

Depois de subirmos o container do SQL Server, vamos criar um database de nome TesteEF e uma tabela de nome Person e habilitar o CDC

Vejam que existe a execução da procedure sys.sp_cdc_enable_db esse comando habilitará o funcionamento do CDC em seu banco de dados.

E a procedure sys.sp_cdc_enable_table vai associar a tabela que será monitorada pelo CDC, no nossa caso a tabela Person

Depois de configurado, vamos subir os containers do Zooekeeper, Kafka e Kafka Connect, para configurarmos o Debezium

Se atentem pelo endereço de IP em KAFKA_ADVERTISED_LISTENERS e BOOTSTRAP_SERVER. Adicionem da máquina que está rodando.

Agora, depois de os containers estarem rodando, vamos configurar no Kafka Connect com o plugin do Debezium, com as configurações de nosso banco de dados

Inicialmente podemos verificar, todos os plugins instalados no Kafka Connect nesta URL: http://seuipservidor:8083/connector-plugins

O serviço do Kafka Connect, te dá essa API, para a consulta dos plugins. E também vamos usar a API para fazer a configuração do plugin do Debezium para SQL Server, que irá monitorar nosso banco de dados.

Fui ao Postman, e na URL http://seuipservidor:8083/connectors, iremos via POST, adicionar as configurações:

Vejam na imagem acima, as configurações para o conector Debezium

database.hostname => Servidor de onde está a sua base de dados

database.port => Porta do SQL Server

database.user => Usuário de seu banco de dados

database.password => Senha do seu banco de dados

database.dbname => Qual o database que irá ser monitorado

database.server.name => Um nome para ser servidor

table.whitelist => Qual tabela sera monitorada

database.history.kafka.bootstrap.servers => Cluster do Kafka

database.history.kafka.topic => Nome do Database que armazenará as mensagens do tópico no Kafka

Depois de adicionar as configurações, vamos executar essa requisição no Postman, e o resultado será esse:

201 (Created)

Com isso a configuração está feita no Kafka Connect.

O nome que será gerado pelo Kafka, para obtermos as mensagens, será a junção dessas propriedades:

database.server.name + table.whitelist

Com isso nosso tópico será: dbserver1.dbo.Person

Antes de fazermos a inserção de algum registro no SQL Server, vou utilizar uma aplicação que fiz de exemplo em C#, que está em meu GitHub, onde vou obter todas as mensagens que forem enviadas do SQL Server pelo Kafka Connect via tópico

Esse console será o consumidor do tópico que o Kafka Connect gerará com as alterações feitas na tabela no SQL Server.

Vejam que na propriedade BootstrapServers, colocaremos o endereço do serviço do Kafka, que está rodando na máquina. E na linha 22, o Subscribe com o nome do tópico.

Rode sua aplicação, e faça um insert em seu banco de dados;

Depois do insert, veja que no console o registro que você inseriu em seu banco de dados.

Agora vamos alterar o registro:

Veja no console a alteração que fez em seu banco de dados

Veja que todas as alterações que eu fizer no SQL Server, a minha aplicação irá conseguir consumir. Isso graças ao Kafka Connect;

Bom pessoal, esse é um exemplo simples, de como resolver um problema que podemos ter em sistemas distribuídos. Estamos aqui usando containers, provavelmente em suas aplicações produtivas, com certeza o melhor será a instalação do Kafka standalone ou Cloud (Confluence) para ter mais performance.

Existem vários problemas que podemos resolver com esse tipo de solução, e espero que esse tipo de artigo, possa ajudar as pessoas a entenderem mais sobre o Kafka e também a resolver alguns problemas;

Dia 31/08, fizemos eu e meu amigo Ray Carneiro, uma live no canal JunDevelopers, falando sobre esse tema. Mas lá temos mais detalhes, e também nesta live usando o connector Sink do Mongo DB, onde o MongoDb recebe as mensagens do tópico do Kafka. Veja lá..

Espero que tenham gostado!

Até a próxima!

--

--

Fernando Mendes
JunDevelopers

Software Architect .NET C# | Microsoft MVP 🏆🏆 | Co-Founder community JunDevelopers