Introdução
Streaming de dados (event streaming, real-time processing) é fundamental para aplicações modernas. Mas arquiteturas event-driven trazem complexidades: como garantir exatamente-once semantics? Como lidar com eventos fora de ordem? Como fazer join entre streams?
Este guia apresenta padrões arquiteturais testados em produção para resolver esses desafios.
Pattern 1: Event Sourcing
O Que É
Armazenar mudanças de estado como sequência imutável de eventos ao invés de sobrescrever estado atual.
Quando Usar
- Necessidade de auditoria completa
- Sistemas financeiros ou críticos
- Event-driven microservices
Implementação com Kafka
Order Created → Kafka Topic (events)
Order Paid → Kafka Topic
Order Shipped → Kafka Topic
Consumer reconstrói estado atual lendo todos eventos
Trade-offs
Prós: Auditoria completa, time travel, event replay Contras: Mais storage, queries mais complexas
Pattern 2: Change Data Capture (CDC)
O Que É
Capturar mudanças em databases e publicá-las como eventos streaming.
Quando Usar
- Sincronizar databases (Oracle → Postgres)
- Alimentar data lakes em tempo real
- Invalidar caches quando dados mudam
Implementação
Database → Debezium CDC → Kafka → Consumers
Vantagens vs Batch ETL
- Latência: Segundos vs horas
- Custo: 60-80% menor (vs GoldenGate)
- Impacto: Minimal em source database
Pattern 3: CQRS (Command Query Responsibility Segregation)
O Que É
Separar modelos de escrita (command) e leitura (query) em diferentes datastores otimizados.
Quando Usar
- Reads e writes têm requisitos muito diferentes
- Necessidade de views materializadas otimizadas
- Escala independente de leitura e escrita
Arquitetura
Write: API → Command Handler → Event Store (Kafka)
Read: Events → Materializer → Read DB (optimized)
Pattern 4: Stream Joins
O Que É
Fazer join entre múltiplos streams de eventos.
Tipos
Stream-Stream Join: Juntar dois streams (e.g., clicks + purchases) Stream-Table Join: Enriquecer stream com dados de tabela (e.g., events + user metadata)
Implementação Flink
Flink suporta windowed joins, temporal joins, interval joins.
Desafios
- Eventos fora de ordem
- Watermarking
- Late arriving events
Pattern 5: Exactly-Once Semantics
O Desafio
Garantir que cada evento seja processado exatamente uma vez (não duplicado, não perdido).
Soluções
Kafka: Idempotent producers + transactional consumers Flink: Distributed snapshots (Chandy-Lamport)
Trade-off
Exactly-once tem overhead de performance (~10-20%). Avalie se at-least-once é suficiente.
Pattern 6: Dead Letter Queue
O Que É
Queue separada para mensagens que falharam processamento após múltiplas tentativas.
Quando Usar
- Garantir que poison messages não bloqueiem pipeline
- Debugging de failures
- Compliance (não perder dados mesmo com erros)
Implementação
Main Topic → Processor → (success) → Output Topic
→ (failure after 3 retries) → DLQ Topic
Conclusão
Streaming é poderoso mas complexo. Patterns testados em produção reduzem risco e aceleram implementação. Os padrões apresentados cobrem 80% dos casos de uso reais.
Próximos passos:
- Identifique qual pattern se aplica ao seu caso
- Implemente PoC com dados reais
- Teste em produção com tráfego pequeno
- Escale gradualmente
Entre em contato para discutir implementação de arquiteturas streaming em seu contexto específico.
