Streaming
O que é streaming
O streaming é uma resposta contínua a uma sequência infinita de eventos (logs de transações, cliques, pagamentos, telemetria), com um mínimo de atraso e garantia de correção de estados. Ao contrário do batch, onde «tomamos todos os dados acumulados durante o período», o fluxo processa os dados à medida que chega, mantém o estado e leva em conta a hora do evento.
Conceitos-chave
Evento é um fato inválido com 'event _ time' e único 'event _ id'.
Tempo de evento (event time) vs tempo de processamento (processing time) - o primeiro vem da origem, o segundo quando a operadora realmente viu o evento.
- Tumbling (não recorrentes), Hopping/Sliding (com sobreposição), Sessão (quebras de inatividade).
- A marca de água (watermarks) é uma avaliação de que «eventos até o momento T já chegaram», permitindo fechar janelas e limitar a espera por dados atrasados.
- Dados atrasados - eventos com 'event _ time' menor do que o watermark atual; as regras de pré-trabalho são frequentemente aplicadas.
- Estado (state) - Tabelas/armazenamento local das operadoras (keyed state) para as unidades, join's, dedução.
- Backpressure - pressão por excesso de largura de banda downstream; controlado por protocolo e buffers.
Bases arquitetônicas
1. Fonte: corretor de eventos (Kafka/NATS/Pulsar), CDC de banco de dados, filas, arquivos/logs coletores.
2. Motor de streaming: calcula janelas, unidades, joynes, pattern (CEP), controla o estado e checkpoint 'ami.
3. Receptor (sink): OLTP/OLAP BD, motor de busca, dinheiro, topics, armazenamento para vitrines/relatórios.
4. Registro de esquemas: controle da evolução do payload e compatibilidade.
5. Observabilidade: métricas, trailing, logs, dashboards de laje e marcas de água.
Semântica de tempo e ordem
Prefira sempre o event time: este é o único invariante com atrasos e interrupções.
Eventos podem vir fora da ordem; a ordem só é garantida dentro da chave de partilha.
- fechar janelas e emitir resultados;
- limitar «quanto tempo esperamos» para eventos atrasados ('allowed _ lateness').
- Para eventos atrasados, use retrações/upserts: reexaminação de unidades e eventos corretivos.
Estado e confiabilidade
Keyed state: os dados das unidades (somas, contadores, estruturas de dedução) são distribuídos em chaves.
Checkpoint/Savepoint: imagens periódicas do estado para recuperação; savepoint é uma imagem controlada para migrar a versão do código.
- «leu-processou-gravou» (commit sink + posição de leitura);
- sinks idênticos (upsert/merge) + tabelas de dedução;
- versionagem de unidades (optimística concurrency).
Janelas, agregações, join's
Janelas:- Tumbling: relatórios periódicos simples (minutos, horas).
- Hopping/Sliding: métricas «deslizantes» (em 5 minutos com um passo de 1 min).
- Sessão: natural para sessões personalizadas e antifrode.
- Aggregations: sum/count/avg/approx-distinct (HyperLogLog), percentiles (TDigest/CKMS).
- Stream-Stream join: requer tampão de ambas as partes na chave e na hora, respeite 'allowed _ skew'.
- Stream-Place join (KTable): conecta o guia ou o estado atual (por exemplo, «limites ativos do usuário»).
Trabalhar com dados atrasados e duplicados
Deduplicação por 'event _ id' ou '(producer _ id, sequence)'; guarde as chaves «vistas» do TTL ≥ da janela de repetição.
Late events: permita o pré-processamento da janela durante 'X' após o fechamento (retrações/upserts).
Falso duplicado: Ajuste as unidades idumpotentemente e instale «ALREADY _ APPLIED» nos logs.
Escala e desempenho
Charding por chave: fornece paralelismo; Vigiem as chaves quentes.
Backpressure: Limite a paralelidade, use batches e compressão ao publicar.
Marcas d' água: Não coloque agressivamente - watermarks rígidos reduzem a espera, mas aumentam a proporção de atualizações late.
Estado: selecione o formato (RocksDB/state store/memória) com base no tamanho e nos patters de acesso; limpa a TTL.
Escala automática: por laje, CPU, tamanho state, tempo GC.
Confiabilidade e reinício
Um sink idumpotente ou um commit de transação com fixação de ofset é a base da correção.
A reaproximação é permitida após o reinício; O efeito deve ficar «exatamente uma vez».
DLQ/check lot: envie registros problemáticos para um fluxo separado com causas; Garanta a readaptação.
Observabilidade (o que medir)
Por fonte (hora e mensagem).
Watermark/current event time e uma proporção de eventos late.
Throughput/latency operadoras, p95/p99 end-to-end.
State size/rocksdb I/O, frequência checkpoint 's/duração.
DLQ rate, porcentagem de deduções/retrações.
CPU/GC/heap, tempo de pausa.
Segurança e Complacência
Classifique os dados: PII/PCI em esquemas, guarde o mínimo, criptografe o state e os snapshots.
ACS: LCA individuais por topics/tabelas state e por sinks.
Reticências: compatíveis com os requisitos legais (GDPR/direito ao esquecimento).
Auditoria: logue 'event _ id', 'trace _ id', resultado: 'APPLIED/ALREADY _ APPLIED/RETRIED'.
Pattern de implementação
1. CDC → normalização → evento de domínio: não transmita alterações crus de banco de dados, mapeie para factos de negócios compreensíveis.
2. Outbox dos produtores: transação + evento em uma transação BD.
3. Core vs Enriched: payload mínimo em fluxo crítico, enriquecimento em asincrona.
4. Amizade replay: projeções/vitrines devem ser reaproveitadas a partir do login.
5. Idempotency by design: operation/event key, circuitos upsert, versões das unidades.
Testes
Unit/Property-based: invariantes de agregados e transformações.
Stream tests: fluxo fixo de eventos com out-of-order e duplicados → verificação de janelas e deduções.
Golden windows: janelas de referência/unidades e ajustes tardios válidos.
Fault-inhation: A queda entre «gravou o efeito» e «comutou o ofset».
Replay testes: cruzamento da vitrine do início do logs = estado atual.
Custo e otimização
As janelas e watermark afetam o atraso/recursos: quanto mais longo e mais 'allowed _ lateness', mais state.
Codecs e compressão: balanceie CPU/rede.
Batching de saída: menos chamadas de rede e transações.
Filtrar cedo («pushdown»): retire o mais perto possível da origem.
Antipattern
Estoque no processing time onde você precisa de um event time → um analista errado.
A falta de idempotidade no sink → efeitos duplos no restarte.
«Mega chaves» globais, uma seção quente quebra o paralelismo.
CDC crus como eventos públicos, fuga de esquemas de BD, fragilidade na evolução.
Sem DLQ, mensagens venenosas bloqueiam toda a linha de montagem.
Atraso forte fixo em vez de watermark, ou espera permanente ou perda de dados.
Exemplos de domínio
Pagamentos/finanças
Fluxo de 'payment', janelas de antifrode (sessions + CEP), dedução de 'operation _ id'.
O efeito exactly-once é disparado em ledger contável (upsert + versão).
Marketing/publicidade
Sliding janelas CTR/Conversões, Join cliques e exibições com suporte de 'Portanto', agregação para bidding.
iGaming/serviços online
Real tempo equilíbrio/limite, missões/acertos (sessão da janela), antifrod pattern e alertas.
Mini-modelos (pseudocode)
Janela com marcas de água e atualizações late
pseudo stream
.withEventTime(tsExtractor)
.withWatermark(maxAllowedLag=2m)
.window(TUMBLING, size=1m, allowedLateness=30s)
.keyBy(user_id)
.aggregate(sum, retractions=enable)
.sink (upsert_table )//idempotent upsert by (user_id, window_start)
Sink transacionado com fixação de ofset
pseudo begin tx upsert target_table using event, key=(k)
update consumer_offsets set pos=:pos where consumer=:c commit
Folha de cheque da produção
- Definidos event time e estratégia watermark; as janelas selecionadas e 'allowed _ lateness'.
- Sink Idumpotent ou Comit de transação ofset.
- O registro de esquemas e os modos de compatibilidade estão incluídos; evolução aditiva.
- Métricas: liga, watermark, p95/p99, DLQ, tamanho state, duração checkpoint.
- Testes: out-of-order, duplicados, reiniciados, replay.
- Políticas PII/Reticência para state e snapshots.
- Plano de zoom e estratégia backpressure.
- Documentação de contratos de janelas e ajustes (late updates).
FAQ
O Event time é obrigatório?
Se o que importa são as métricas corretas e a coerência, sim. O Processing time é adequado para pagamentos/monitoramento, mas distorce o analista.
É necessário exactly-once?
Pontualmente, para efeitos críticos. Na maioria das vezes, basta um sink-least-once + idumpotente.
Como escolher as janelas?
Afaste-se do SLA de negócios: «nos últimos 5 minutos» hopping, «sessões de usuário», «sessão», «relatórios de minutos» tumbling.
O que fazer com os dados tardios?
Permitir «allowed _ lateness» limitado e emitir ajustes (upsert/retract). A vitrine do cliente tem de ser atualizada.
Resultado
O streaming não é apenas um atraso baixo, mas também uma disciplina de tempo, estado e contratos. A escolha correta de event time, janelas e marcas de água, além de efeitos idimpotentes, observabilidade e testes tornam a linha de montagem confiável, reproduível e econômica - e dão ao negócio soluções «aqui e agora», em vez de «à noite».