Change Data Capture (CDC)
Conceito e prática
Neste artigo, pretendo trazer conceitos iniciais sobre a captura de mudança de dados e um exemplo prático para firmar os conceitos apresentados.
O que é CDC e por que existe?
Como o próprio nome diz, CDC é uma técnica que busca monitorar e capturar quaisquer mudanças nos dados, permitindo que outras aplicações sejam capazes de reagir a essas mudanças e.g. construção da linha temporal dos dados. Além de auxiliar na construção de um histórico, essa técnica também é utilizada para realizar a replicação entre instâncias de bancos de dados.
Como isso acontece?
Para realizar o CDC é necessário que quaisquer alterações do banco de dados de origem sejam armazenadas em algum lugar. Para isso, os dados das operações são guardados em arquivos de log. No MySQL é chamado de binlog. Esses arquivos normalmente têm um tamanho limitado, apagando registros mais antigos para que os mais recentes possam ser armazenados. Tal abordagem é utilizada para que o binlog não consuma todo o armazenamento disponível.
O binlog é monitorado por outras aplicações para que seja possível tratar os dados assim que eles entram no banco, não sendo mais necessário utilizar soluções paliativas como, por exemplo, selects com filtros de tempo.
Como o CDC acontece na prática?
Agora que entendemos como funciona o binlog vamos ver como nossa arquitetura de funciona na prática. E antes de partirmos para o mão na massa, recomendo que baixem o seguinte repositório do github (https://github.com/armandobs14/cdc-debezium). Além disso, certifique-se que tem docker e docker-compose instalados.
Arquitetura de CDC
Para montar um exemplo prático de CDC iremos utilizar a arquitetura a seguir (Figura 2). Através dela, iremos capturar as operações de insert, update e delete realizadas em no MySQL utilizando o debezium e enviando-as para um tópico do kafka.
Ok, mas que é o debezium, kafka e zookeeper?
Debezium trata-se de uma solução de código aberto desenvolvida pela Red Hat que tem por objetivo monitorar quais quer alterações nos dados, permitindo que as aplicações possam reagir à mudanças específicas.
Kafka é uma plataforma de stream de código aberto implementada em Scala e Java. Ela foi desenvolvida originalmente pelo LinkedIn e atualmente faz parte Apache Software Foundation (ASF). O Kafka também conta com uma versão fechada que é desenvolvida pela Confluent, que é uma empresa formada pelos desenvolvedores do kafka que sairam do LinkedIn e montaram uma empresa.
Zookeeper ou Apache Zookeeper também é uma solução de código aberto também mantido pela ASF. Trata-se de um serviço centralizador de configurações e nomes. Consequentemente, permite que as aplicações distribuídas consigam compartilhar informação facilmente.
DEMO
Suba os contêineres utilizando o docker-compose
docker-compose up -d
Verifique que o endpoint do kafka-connect está disponível
curl -H “Accept:application/json” localhost:8083
Agora devemos cadastrar o nosso conector do MySQL
bash debezium.sh
O arquivo debezium.sh cadastra o conector do MySQL com parâmetros pré-configurados. Caso queira conhecer todos os parâmetros consulte a documentação oficial. Vale a pena ressaltar que é possível incluir ou excluir bancos, tabelas e colunas os itens monitorados pelo kafka-connect. Isso é muito importante quando precisamos anonimizar alguma coluna, garantindo assim o sigilo dos usuários por exemplo.
Para acompanhar as alterações capturadas via CDC podemos utilizar o script Python na pasta client.
python3 client/consumer.py --h localhost:9092 --t dbserver1.inventory.customers
O próximo passo é executar consultas no banco de dados. Para isso, entre no contêiner do MySQL
docker exec -ti mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"'
Dentro do MySQL realize um insert
mysql> insert into inventory.customers VALUES (1005,'Armando','Barbosa','armando@email.com');
Após a execução do insert observe o script Python que está em execução e lá estará a alteração refletida. Com metadados sobre o registro, sendo eles: como estava antes (before), como ficou depois (after), tipo de operação (op) e fonte (source). Como pode ser visto a seguir:
{
"after": {
"email": "armando@email.com",
"first_name": "Armando",
"id": 1005,
"last_name": "Barbosa"
},
"before": null,
"op": "c",
"source": {
"connector": "mysql",
"db": "inventory",
"file": "mysql-bin.000003",
"gtid": null,
"name": "dbserver1",
"pos": 364,
"query": null,
"row": 0,
"server_id": 223344,
"snapshot": "false",
"table": "customers",
"thread": 13,
"ts_ms": 1614570860000,
"version": "1.4.1.Final"
},
"transaction": null,
"ts_ms": 1614570860346
}
Conclusão
Neste artigo entendemos os conceitos iniciais de CDC bem como vimos um exemplo prático para firmar os conceitos aprendidos. Vale a pena ressaltar que todo o código utilizado nesse artigo está presente no seguinte repositório https://github.com/armandobs14/cdc-debezium.
Estejam convidados para contribuir, no código ou no artigo. Espero que tenham gostado e até a próxima.