O que é Data Streaming na AWS: Kinesis, Data Firehose, Flink e MSK (e quando usar cada um)
Data streaming na AWS: o que é, e quando usar Kinesis Data Streams, Amazon Data Firehose, Managed Service for Apache Flink e MSK.

Staff Engineer @Serverless Guru | AWS Community Builder | Specialist in Serverless, AWS & Event-Driven Architectures | Speaker & Content Creator @willpeixoto.dev
Tem um tipo de dado que não pode esperar. A transação suspeita que precisa ser barrada agora, não amanhã no relatório. O clique do usuário que, se você lê na hora, vira recomendação certeira, e se lê depois, vira oportunidade perdida. Por muito tempo a gente tratou tudo igual: junta um monte de dado, guarda num banco, e processa em lote mais tarde. Só que tem coisa que vive no agora.
A imagem que me ajuda a explicar isso é a de um rio. Repara que a água não para pra ser usada. Ela passa, e quem está na margem aproveita no caminho: um move a roda do moinho, outro irriga a plantação, outro gera energia. Ninguém represa tudo primeiro pra só então usar. Agora troca a água por dado e você tem data streaming: a informação chega num fluxo contínuo e você reage no instante em que ela passa, em vez de empilhar tudo pra processar lá na frente.
É essa diferença que separa reagir de só descobrir depois. Um banco que barra a fraude no segundo da transação, um e-commerce que recomenda no clique, uma fábrica que ajusta a máquina antes de ela quebrar: em todos, processar depois é quase não processar, porque quando o batch da meia-noite roda o momento já passou.
Só que "streaming na AWS" confunde, porque são quatro serviços de nomes parecidos e até gente boa erra qual usar. Vem comigo que eu separo.
Antes do serviço, o conceito: stream ou batch
Batch é juntar um monte de dado e processar de tempos em tempos, tipo o relatório que roda de madrugada. Streaming é processar evento a evento, conforme chega. Não competem: cada um resolve um tipo de problema. Fechamento contábil do mês é batch e está ótimo. Alerta de fraude é streaming, porque um minuto de atraso já é dinheiro perdido. O erro é usar batch onde o negócio precisa reagir na hora.
O mapa: os quatro serviços (e o que cada um faz de verdade)
Antes de entrar em cada um, dois avisos que evitam confusão. Primeiro, a AWS renomeou dois serviços: o Kinesis Data Firehose virou Amazon Data Firehose (fev/2024) e o Kinesis Data Analytics virou Amazon Managed Service for Apache Flink (ago/2023). Se você achar tutorial com o nome antigo, é o mesmo serviço, só trocou a placa. E o Data Streams ganhou um modo novo, o On-demand Advantage, que eu explico já já.
Segundo, pra quem vem do Kafka: o que lá é topic, aqui no Kinesis é stream; o que lá é partition, aqui é shard. Daqui pra frente eu uso o nome certo de cada serviço, mas saiba que os dois mundos se espelham.
Kinesis Data Streams: o rio que você pode reler
É o coração da história. O stream (o topic, lembra?) é durável: produtores escrevem, consumidores leem, e o dado fica retido por um tempo (até 365 dias), então dá pra reprocessar. É o "log" do rio. A capacidade vem dividida em shards (as partitions), e cada shard tem um teto de escrita e leitura. Você escolhe o modo:
Provisioned: você define o número de shards e paga por eles, ligados ou não.
On-demand: a AWS gerencia os shards sozinha e você paga pelo throughput que usa.
On-demand Advantage (o mais novo): traz warm throughput, com capacidade instantânea pra picos, até 10 GiB/s. Use quando você precisa de um stream durável, com replay, e vai construir o consumer (uma Lambda, ou um app com a Kinesis Client Library, a KCL, que cuida da distribuição de shards e do checkpoint pra você).
Amazon Data Firehose: só me entrega num destino
Esse foi renomeado de Kinesis Data Firehose em 2024, mesma coisa, nome novo. Aqui você não escreve consumer, é o papel que o Kafka Connect faz no mundo Kafka (os sink connectors). Você aponta uma fonte e um destino (S3, OpenSearch, Redshift e outros) e o Firehose entrega, com buffering, transformação opcional e compressão no caminho. Não tem replay, é entrega quase em tempo real. Use quando o objetivo é pegar o stream e jogar num lugar, sem lógica de consumo própria.
Managed Service for Apache Flink: processamento COM estado
Esse era o Kinesis Data Analytics, renomeado em 2023. Roda Apache Flink gerenciado pra processamento com estado, o que o Kafka Streams ou o ksqlDB fazem no mundo Kafka: janelas (somar por minuto), joins entre streams, exactly-once. Quando a pergunta é "qual a média móvel dos últimos 5 minutos por usuário", a resposta mora aqui. O estado, o checkpoint e a recuperação são responsabilidade do serviço, não sua.
Amazon MSK (e MSK Serverless): Kafka gerenciado
Se o teu mundo já é Kafka (ecossistema, Kafka API, portabilidade entre nuvens, time que manja), o MSK é o Kafka gerenciado da AWS. O MSK Serverless provisiona e escala as partições sozinho, sem você dimensionar cluster. Use quando você precisa do Kafka de verdade, não de um equivalente nativo.
Quando usar cada um
| Você quer... | Serviço AWS | Equivalente no Kafka |
|---|---|---|
| stream durável e replayável, com consumer seu | Kinesis Data Streams | Apache Kafka (Amazon MSK) |
| só entregar o stream num destino, sem escrever código | Amazon Data Firehose | Kafka Connect (sink) |
| processamento com estado (janela, join, agregação) | Managed Service for Apache Flink | Kafka Streams / ksqlDB |
Na vida real, muita arquitetura combina esses serviços em três camadas: entrada, entrega e processamento. Data Streams na entrada, Firehose entregando uma cópia crua no S3 pra histórico, e Flink processando em tempo real pra dashboard. E a entrada não precisa ser o Data Streams: dá pra ter MSK na frente e o Flink depois, porque o Managed Flink lê tanto do Kinesis quanto do MSK.
Mão na massa: produtor e consumidor no Kinesis Data Streams
O produtor escreve eventos no stream. Repara na PartitionKey: é ela que decide em qual shard o registro cai, e portanto a ordem.
import { KinesisClient, PutRecordsCommand } from "@aws-sdk/client-kinesis";
const kinesis = new KinesisClient({});
await kinesis.send(new PutRecordsCommand({
StreamName: "eventos-clientes",
Records: [
{
Data: Buffer.from(JSON.stringify({ userId: "u-42", evento: "clique", ts: Date.now() })),
PartitionKey: "u-42", // mesma chave por usuario = ordem preservada por usuario
},
],
}));
O consumidor, no jeito serverless, é uma Lambda com event source mapping no stream. Ela recebe os registros em lote, já na hora que passam:
export async function handler(event) {
for (const record of event.Records) {
const payload = JSON.parse(Buffer.from(record.kinesis.data, "base64").toString());
// processa o evento no momento em que ele passa
console.log(payload.userId, payload.evento);
}
}
Um detalhe importante aqui: a ordem é garantida por shard (por partition key), não no stream inteiro. Se a ordem importa pra uma entidade (um usuário, um pedido), use a chave dessa entidade como partition key. Senão, os eventos espalham pelos shards e a ordem global vira ilusão.
Pra ficar concreto, o mesmo par de eventos com e sem ordenação:
const enc = (o) => Buffer.from(JSON.stringify(o));
// COM ordem: a partition key é a entidade (userId). Os dois eventos do "u-42"
// caem no mesmo shard, na ordem em que entraram.
await kinesis.send(new PutRecordsCommand({ StreamName: "eventos-clientes", Records: [
{ Data: enc({ userId: "u-42", evento: "login" }), PartitionKey: "u-42" },
{ Data: enc({ userId: "u-42", evento: "compra" }), PartitionKey: "u-42" },
]}));
// SEM ordem: partition key aleatória por evento. Eles podem cair em shards
// diferentes, e a ordem entre os dois vira sorte.
await kinesis.send(new PutRecordsCommand({ StreamName: "eventos-clientes", Records: [
{ Data: enc({ userId: "u-42", evento: "login" }), PartitionKey: crypto.randomUUID() },
{ Data: enc({ userId: "u-42", evento: "compra" }), PartitionKey: crypto.randomUUID() },
]}));
No primeiro bloco, o consumidor sempre vê "login" antes de "compra". No segundo, pode vir trocado, porque a ordem só existe dentro de um shard.
Os trade-offs honestos
Ordenação e escala: a ordem é por shard, não global. E a escolha da partition key não é um detalhe, é uma decisão de design que define como a sua aplicação se comporta E como ela escala. Chave enviesada joga tráfego demais num shard só (o hot shard) e você perde throughput mesmo pagando por vários. Isso sozinho rende um post inteiro, e vai ter.
Retenção e replay: Data Streams retém e deixa reprocessar; Firehose não, ele entrega e segue.
Custo: provisioned paga shard mesmo parado; on-demand paga uso. Stream ligado 24/7 com tráfego previsível às vezes sai mais barato provisionado. Custo é decisão de arquitetura, como o Werner Vogels martela no Frugal Architect.
Latência: streaming é baixa, mas não é zero. O Firehose ainda tem buffering (de segundos a minutos), então não conte com ele pra reação instantânea.
Kinesis ou MSK?
Se você não tem compromisso com Kafka, o Kinesis é mais simples e nativo, casa melhor com Lambda e o resto do serverless. Se você já vive de Kafka (conectores, ferramentas, multi-cloud, time treinado), o MSK te dá o Kafka sem você operar o cluster na unha. A escolha é de contexto e ecossistema; "qual é o melhor" é a pergunta errada.
O que você leva
Data streaming é processar no fluxo, em tempo real, pra reagir no momento (fraude, recomendação, IoT). Batch é pra quando o atraso não dói.
Kinesis Data Streams é o stream durável e replayável; Amazon Data Firehose entrega num destino; Managed Service for Apache Flink faz processamento com estado; MSK é Kafka gerenciado.
A ordem é por shard, então escolha a partition key com intenção.
Provisioned ou on-demand é decisão de custo, e arquitetura real combina os serviços em vez de escolher um só. Você usa streaming em algum projeto? Conta qual desses quatro entrou no teu desenho, e se já te queimou escolher o errado. Manda aquele joinha, compartilha com quem ainda processa tudo no batch da meia-noite, e bora trocar ideia. Valeu demais! =D





