Um banco muda.
O restante do sistema precisa saber.
Essa frase parece simples até você tentar implementá-la com garantias razoáveis em produção.
No começo, muita equipe faz o caminho direto: depois do commit, a aplicação publica um evento no Kafka. Se falhar, tenta de novo. Se cair, algum job reconcilia. Se duplicar, o consumidor que lute com idempotência.
Às vezes funciona.
Às vezes vira uma coleção de janelas invisíveis entre banco, aplicação e broker.
O dado foi confirmado no banco, mas o evento não saiu. Ou saiu duas vezes. Ou saiu com payload diferente do estado gravado. Ou saiu antes de uma transação que depois falhou. Ou saiu por um caminho que ninguém consegue reprocessar depois do incidente.
CDC, Change Data Capture, existe porque essa fronteira é mais séria do que parece.
Debezium ficou conhecido nesse espaço porque capturar mudanças confirmadas no banco, transformá-las em eventos e publicá-las no Kafka não deveria depender de improviso dentro de cada aplicação.
Ele não é a única ferramenta capaz de fazer isso, mas é um bom exemplo do tipo de infraestrutura que aparece quando o problema deixa de ser "publicar uma mensagem" e passa a ser "operar um fluxo confiável de mudanças confirmadas".
O problema não é detectar mudança
Detectar que uma tabela mudou é fácil quando a régua é baixa.
Você pode comparar timestamps.
Pode criar uma trigger.
Pode fazer polling em uma coluna updated_at.
Pode gravar uma linha em uma tabela auxiliar.
O problema não é perceber que algo mudou em algum momento.
O problema é capturar mudanças na mesma ordem em que foram confirmadas, sem perder transações, sem publicar dados que sofreram rollback, sem depender de consultas frágeis e sem inventar um protocolo diferente para cada serviço.
Em produção, a pergunta real não é:
"como eu descubro que a tabela mudou?"
A pergunta é:
"como eu transformo mudanças confirmadas no banco em um fluxo confiável de eventos que outros sistemas conseguem consumir?"
É aí que CDC deixa de ser detalhe de infraestrutura e vira decisão arquitetural.
O log do banco já sabe a verdade
Bancos relacionais não confirmam transações por mágica.
Eles registram alterações em logs transacionais.
PostgreSQL tem WAL. MySQL tem binlog. SQL Server, Oracle e outros bancos têm mecanismos equivalentes.
Esses logs existem para durabilidade, replicação, recuperação e consistência interna do próprio banco.
Quando uma transação é confirmada, o banco precisa conseguir provar o que aconteceu e em que ordem aquilo aconteceu.
CDC aproveita essa fonte.
Em vez de perguntar para a tabela "o que parece novo agora?", uma ferramenta de CDC acompanha o log transacional e observa mudanças confirmadas.
Essa diferença é enorme.
Polling em tabela enxerga estado atual.
CDC enxerga a sequência de mudanças.
Se um pedido muda de CREATED para PAID e depois para CANCELLED, uma consulta periódica talvez veja apenas o estado final.
Um fluxo baseado em log consegue representar a história das mudanças, desde que esteja configurado para isso.
Para integração orientada a eventos, essa diferença separa sincronização preguiçosa de fluxo operacionalmente rastreável.
Onde ferramentas como Debezium entram
Debezium é uma plataforma de CDC.
Na prática, ele conecta no banco, lê o log transacional, entende o formato de mudanças daquele banco e publica registros em Kafka.
Existem outras formas e outras ferramentas para fazer CDC, dependendo do banco, da nuvem, da stack de dados e do nível de controle que a equipe precisa. O ponto aqui não é vender Debezium como única resposta. É entender por que uma ferramenta especializada passa a fazer sentido.
Ele não existe porque publicar no Kafka seja difícil. Ele existe porque fazer isso direito, para bancos diferentes, com retomada, offsets, snapshot inicial, schema, tipos de dados, deletes, updates, transforms e observabilidade, é trabalho demais para ser reinventado por cada time de aplicação.
Sem uma ferramenta desse tipo, cada serviço tende a criar sua própria versão:
- um job que consulta
updated_at; - uma trigger que grava JSON em uma tabela;
- um worker que publica e marca como enviado;
- um script de reconciliação;
- uma rotina especial para carga inicial;
- uma lógica própria para retry e duplicidade.
Algumas dessas soluções são válidas em contextos pequenos. O problema aparece quando elas viram infraestrutura crítica sem terem sido tratadas como infraestrutura crítica.
Ferramentas como Debezium tentam padronizar essa fronteira. Elas assumem o papel de leitor das mudanças do banco e produtor dessas mudanças no Kafka, tirando essa responsabilidade do fluxo de negócio da aplicação.
CDC não substitui modelagem de evento
Um erro comum é achar que CDC resolve modelagem.
Não resolve.
CDC consegue publicar mudanças de tabela.
Isso não significa que toda mudança de tabela seja um bom evento de negócio.
Uma linha alterada em orders pode ser apenas persistência interna.
Um evento OrderPaid é um contrato de domínio.
Essas coisas podem se aproximar, mas não são automaticamente iguais.
Se você publica CDC bruto de todas as tabelas, consumidores passam a depender de nomes de colunas, detalhes de normalização, estrutura interna do banco e decisões locais do serviço produtor.
Nesse desenho, o banco vira contrato público.
E isso cobra caro quando você precisa refatorar tabela, separar colunas, mudar enum, ajustar relacionamento ou corrigir um detalhe de persistência que nunca deveria ter vazado.
Foi por isso que a série já insistiu em evento como contrato e em schema como contrato de dados.
Debezium transporta mudança.
A arquitetura ainda precisa decidir qual mudança deve virar contrato.
A conexão com Outbox
CDC fica especialmente forte quando usado com Outbox Pattern.
No post sobre Outbox Pattern, a ideia central era simples: a mudança de negócio e a intenção de publicar um evento precisam ser persistidas na mesma transação local.
CDC pode ser o mecanismo que tira essa intenção da tabela outbox e leva para o Kafka.
O fluxo fica assim:
- a aplicação valida a regra de negócio;
- grava o estado principal;
- grava um registro na outbox com o evento desejado;
- confirma a transação;
- uma ferramenta de CDC lê a mudança confirmada no log do banco;
- essa ferramenta publica o evento no Kafka.
A vantagem é clara: a aplicação não precisa publicar no Kafka dentro do caminho transacional da regra de negócio.
Ela grava no banco, que é o recurso transacional que ela controla.
Depois, uma infraestrutura especializada observa a mudança confirmada e publica.
Isso não elimina todos os cuidados.
Consumidores ainda precisam ser idempotentes. Eventos ainda precisam ter schema. A outbox precisa de política de retenção. O time precisa saber operar conectores.
E existe uma decisão econômica importante aqui.
Às vezes, o conector custa mais do que o problema.
Se o volume é baixo, o domínio é simples e o time não tem maturidade operacional para CDC, uma outbox com polling bem implementado pode ser mais barata, mais previsível e suficiente.
Quando esse custo fecha, a fronteira fica mais limpa: decisão de negócio e intenção de evento entram juntas no banco, enquanto a publicação sai por um caminho feito para ler mudanças confirmadas.
O custo que vem junto
Debezium não é mágica operacional.
Ele adiciona peças ao sistema.
Você passa a cuidar de conectores, permissões no banco, slots de replicação, snapshot inicial, lag do conector, evolução de schema, transforms, tópicos gerados, retenção, monitoramento e recuperação depois de falha.
Também precisa entender o impacto no banco. CDC lê uma fonte crítica e não deveria competir com a transação de negócio, mas uma configuração ruim pode pressionar exatamente o lugar errado.
Snapshot mal planejado pode gerar carga inesperada. Slot de replicação abandonado pode segurar logs por tempo demais. Transformação pesada pode aumentar latência. Conector sem limite, sem filtro ou sem sizing adequado pode virar custo permanente no banco e na infraestrutura ao redor.
Em alguns ambientes, esse custo é aceitável. Em outros, torna a solução com CDC mais cara do que um worker simples lendo uma outbox por polling.
Essa comparação não é sinal de arquitetura menor. É engenharia.
Observabilidade não é opcional
O pior tipo de falha em CDC é a falha silenciosa.
O banco continua recebendo transações.
A aplicação continua respondendo.
Kafka continua de pé.
Mas o conector parou.
Ou está preso em erro.
Ou perdeu permissão.
Ou está acumulando lag há horas.
Ou deixou de publicar um subconjunto de mudanças depois de uma alteração de schema.
Quando ninguém observa essa fronteira, o time só descobre dias depois, quando uma projeção está desatualizada ou uma reconciliação mostra que o mundo fora do banco ficou para trás.
Por isso, operar CDC exige métricas e alertas específicos:
- conector rodando ou parado;
- lag de leitura do log;
- idade do último evento publicado;
- erros de task e restart automático;
- crescimento de logs retidos no banco;
- volume esperado por tópico;
- falhas de transformação e serialização.
Não basta ter dashboard bonito do Kafka.
O ponto crítico está entre o banco, o conector e o tópico.
Se essa ponte para e ninguém percebe, o sistema volta exatamente para o problema que CDC prometia reduzir: mudanças confirmadas em um lugar e invisíveis no restante da arquitetura.
Quando Debezium costuma valer a pena
Debezium, Kafka Connect e conectores bem operados resolvem problemas reais, mas também criam um domínio operacional próprio.
Por isso Debezium costuma fazer mais sentido quando o problema justifica esse domínio:
- integração entre domínios que dependem de mudanças confirmadas;
- outbox com publicação confiável para Kafka;
- necessidade de rastrear sequência de alterações;
- volume ou criticidade que tornam polling frágil;
- vários consumidores dependentes do mesmo fluxo;
- equipe capaz de operar Kafka Connect, conectores e observabilidade.
Se a equipe só precisa publicar alguns eventos de outbox por minuto, com SLA moderado e baixo risco de acúmulo, polling pode vencer.
Um worker simples pode buscar linhas pendentes em lotes pequenos, publicar no Kafka, marcar como publicado, expor métrica de atraso e alertar quando acumular.
Ele ainda precisa de cuidado. Polling mal feito também perde evento, duplica publicação, cria lock desnecessário e esmaga banco.
Mas quando bem dimensionado para um problema pequeno, pode ser mais barato do que operar toda a cadeia de CDC.
CDC é uma ferramenta forte.
Ferramenta forte sem problema compatível vira complexidade distribuída com outro nome.
O ponto que vale fixar
Ferramentas como Debezium existem porque a fronteira entre banco e Kafka não deveria depender de sorte entre duas linhas de código.
CDC usa uma fonte mais próxima da verdade do banco: o log transacional.
Isso permite transformar mudanças confirmadas em fluxo de eventos com mais rastreabilidade, ordem e capacidade de retomada do que polling improvisado.
Mas CDC não decide sozinho o que é evento de negócio.
Ele transporta mudanças.
A arquitetura ainda precisa modelar contratos, proteger consumidores contra duplicidade, observar falhas e escolher quando essa infraestrutura vale o custo.
CDC mal observado pode parar por dias sem ninguém perceber. CDC mal configurado pode cobrar caro do banco. E CDC escolhido cedo demais pode ser menos econômico do que uma outbox com polling simples, explícito e bem monitorado.
O ponto não é usar Debezium porque é moderno.
É usar Debezium, ou qualquer ferramenta de CDC equivalente, quando o sistema precisa que mudanças confirmadas no banco atravessem para Kafka de forma operacionalmente confiável e quando o custo operacional dessa ponte faz sentido.
