Apache Flink no K8s e Kafka: PyFlink, Go, operações e preços gerenciados
Streaming com estado, checkpoints, K8s, PyFlink, Go.
O Apache Flink é uma estrutura para computações com estado sobre fluxos de dados ilimitados e limitados.
As equipes adotam a ferramenta para streaming correto e de baixa latência com semântica de tempo de evento (marcas d’água), tolerância a falhas (checkpoints), atualizações controladas (savepoints) e superfícies operacionais (métricas e REST).

Este guia é destinado a equipes de DevOps e desenvolvedores Go/Python. Ele compara modelos de implantação (gerenciado vs. auto-gerenciado), explica a arquitetura central, aborda configurações do Kubernetes (Helm e Operator) e setups independentes, contrasta o Flink com Spark, Kafka Streams, Beam e bancos de dados de streaming, e mostra padrões de integração PyFlink e Go, incluindo pipelines orientados a LLM e IA.
Para um contexto mais amplo sobre padrões de infraestrutura de dados, incluindo armazenamento de objetos, bancos de dados e mensageria, consulte Infraestrutura de Dados para Sistemas de IA: Armazenamento de Objetos, Bancos de Dados, Busca e Arquitetura de Dados de IA.
O que é Apache Flink e por que as equipes o usam para processamento em tempo real
O Apache Flink é posicionado explicitamente como um motor de processamento de fluxo com estado: você modela sua lógica como um pipeline de operadores e o Flink executa-o como um fluxo de dados distribuído com estado gerenciado e semântica de tempo. Na documentação moderna do Flink, o projeto descreve-se como uma estrutura e motor de processamento distribuído para computações com estado sobre fluxos de dados ilimitados e limitados.
De uma perspectiva prática de DevOps/engenharia de software, o Flink é uma boa opção quando você precisa de pelo menos uma das seguintes propriedades:
Se você precisa de junção/agregação/enriquecimento com baixa latência e garantias de correção, você geralmente usa o processamento de tempo de evento do Flink, onde o “tempo” é quando o evento ocorreu (não quando chegou), e as marcas d’água comunicam o progresso do tempo de evento através do pipeline.
Se você precisa de computação com estado em escala (contadores rolantes, sessões, regras de fraude, engenharia de recursos), o Flink trata o estado como parte de primeira classe do modelo de programação e o torna tolerante a falhas via checkpointing.
Se você precisa de streaming operacionalmente robusto (falhas, atualizações rolantes, reinicializações), o Flink faz checkpoints do estado e das posições do fluxo para que o trabalho possa recuperar-se e continuar com as mesmas semânticas “como uma execução sem falhas”.
Casos de uso típicos para DevOps, Go, Python e equipes de IA
O Flink é amplamente utilizado para “pipelines de dados & ETL”, “análises de streaming” e “aplicações orientadas a eventos” (as categorias usadas pela documentação do Flink).
Para uma pilha DevOps + Go/Python, os padrões típicos são os seguintes:
Um serviço Go produz eventos para o Kafka; o Flink consome esses eventos, realiza processamento com estado (ex: deduplicação, agregação em janelas, enriquecimento) e, em seguida, escreve fatos derivados de volta ao Kafka ou a um banco de dados. Os mecanismos de operador e checkpointing do Flink existem para tornar esses pipelines com estado seguros para produção.
Para equipes de ML/LLM, o PyFlink cita explicitamente cenários como “previsão de aprendizado de máquina” e carregamento de modelos de aprendizado de máquina dentro de UDFs em Python como uma motivação de gerenciamento de dependências, o que é um endosso direto de padrões de “trabalho do Flink como runtime de inferência online / engenharia de recursos”.
Arquitetura e recursos centrais do Apache Flink
Arquitetura de cluster do Apache Flink para implantações em produção
O tempo de execução do Flink consiste em dois tipos de processo: JobManager e TaskManagers. A documentação enfatiza que os clientes submetem o fluxo de dados ao JobManager; o cliente pode então desconectar-se (modo desanexado) ou permanecer conectado (modo anexado).
O JobManager coordena a execução distribuída: agendamento, reação à conclusão/falha de tarefas, coordenação de checkpoints e coordenação de recuperação. Internamente, inclui: ResourceManager (slots/recursos), Dispatcher (REST + Interface Web + criação de JobMaster por trabalho) e JobMaster (gerencia um trabalho).
Os TaskManagers executam os operadores/tarefas e trocam/tamponam fluxos de dados. A menor unidade de agendamento é o slot de tarefa; vários operadores podem executar em um único slot (encadeamento de operadores e compartilhamento de slots afetam isso).
Encadeamento de operadores e slots de tarefa para controle de desempenho e custo
O Flink encadeia subtarefas de operadores em tarefas, onde cada tarefa é executada por uma única thread. Isso é descrito como uma otimização de desempenho que reduz a sobrecarga de transferência de threads e de tamponamento, aumentando a taxa de transferência e diminuindo a latência.
Os slots são importantes operacionalmente porque são a unidade de agendamento/isolamento de recursos. O Flink observa que cada TaskManager pode ter um ou mais slots de tarefa; o slotting reserva memória gerenciada por slot, mas não isola a CPU.
Processamento de tempo de evento, marcas d’água e dados tardios
O Flink suporta múltiplas noções de tempo — tempo de evento, tempo de ingestão, tempo de processamento — e usa marcas d’água para modelar o progresso no tempo de evento.
Para trabalhar com tempo de evento, o Flink precisa de carimbos de tempo atribuídos aos eventos e marcas d’água geradas; a documentação oficial “Gerando Marcas d’Água” explica a atribuição de carimbos de tempo e a geração de marcas d’água como os blocos de construção centrais, sendo WatermarkStrategy a maneira padrão de configurar estratégias comuns.
Tolerância a falhas: checkpoints versus savepoints em sistemas reais
O checkpointing existe porque “cada função e operador no Flink podem ter estado”; o estado deve ser checkpointado para se tornar tolerante a falhas. Os checkpoints permitem a recuperação de estado e posições do fluxo para que a execução possa retomar com semânticas livres de falhas.
O Flink é muito explícito ao afirmar que savepoints são “uma imagem consistente do estado de execução de um trabalho de streaming, criada via mecanismo de checkpointing do Flink”, usada para parar e retomar, bifurcar ou atualizar trabalhos. Os savepoints residem em armazenamento estável (ex: HDFS, S3).
A página oficial “Checkpoints vs Savepoints” enquadra a diferença como backups versus logs de recuperação: os checkpoints são frequentes, leves e gerenciados pelo Flink para recuperação de falhas; os savepoints são gerenciados pelo usuário e usados para operações controladas como atualizações.
Opções de implantação e planos de preços do Apache Flink
Opção gratuita/auto-gerenciada do Apache Flink
O tempo de execução de código aberto do Flink é “gratuito” no sentido de licenciamento, mas em produção você paga pela infraestrutura e esforço operacional.
O Flink é projetado para se integrar com gerencadores de recursos comuns (ex: YARN e Kubernetes) e também pode ser executado como um cluster independente ou como uma biblioteca.
Impulsionadores de custos auto-gerenciados para o Apache Flink
Os custos de computação e memória são impulsionados pelo JobManager e pelos TaskManagers, e pelo seu layout de paralelismo/slots. A documentação de configuração do Flink cita explicitamente jobmanager.memory.process.size, taskmanager.memory.process.size, taskmanager.numberOfTaskSlots e parallelism.default como botões centrais para setups distribuídos.
O disco local é um custo oculto frequente para trabalhos com estado. O Flink observa que io.tmp.dirs armazena dados locais, incluindo arquivos RocksDB, resultados intermediários derramados e JARs em cache; se esses dados forem excluídos, isso pode forçar “uma operação de recuperação pesada”, então eles devem residir em armazenamento que não seja purgado periodicamente.
O custo de armazenamento de objetos/arquivos duráveis é impulsionado por diretórios de checkpoint/savepoint. Na configuração Flink 2.x, checkpoints e savepoints são configurados via execution.checkpointing.dir e execution.checkpointing.savepoint-dir e aceitam URIs como s3://… ou hdfs://….
Planos gerenciados do Apache Flink e modelos de faturamento típicos
Serviços gerenciados reduzem o custo operacional, mas adicionam taxas de plataforma e restrições. Os detalhes dependem do provedor.
O Amazon Managed Service for Apache Flink cobra por KPU (1 vCPU + 4 GB de memória por KPU) e cobra por duração e número de KPUs em incrementos de um segundo. A AWS também cobra uma KPU adicional de “orquestração” por aplicativo e taxas separadas de armazenamento/backup.
O Confluent Cloud for Apache Flink é baseado no uso e serverless: você cria um pool de computação e é cobrado pelos CFU consumidos por minuto enquanto as declarações estão sendo executadas. A página de faturamento inclui um exemplo de preço de CFU de US$ 0,21 por CFU-hora (dependente da região) e enfatiza que você pode limitar gastos via máximos de pool de computação.
Aiven e Alibaba Cloud são provedores gerenciados de Flink notáveis no mercado, mas seus preços públicos e detalhes de faturamento variam por plano/região e podem exigir calculadoras ou contato com vendas; trate custos exatos como não especificados a menos que você cotize uma região+plano de sua documentação atual.
A Ververica oferece opções de implantação auto-gerenciada e gerenciada ao redor do Flink; páginas públicas enfatizam escolhas de implantação e posicionamento de serviço gerenciado, enquanto o preço exato é geralmente tratado via fluxos de “contato/detalhes de preço” (então números específicos são frequentemente não especificados publicamente).
Tabela de opções de implantação para Apache Flink em produção
| Opção de implantação | Melhor para | Complexidade operacional | Benefícios chave | Riscos / Compensações chave |
|---|---|---|---|---|
| Cluster independente (VMs/hardware nu) | Pequenas equipes, capacidade fixa | Média–Alta | Controle total; modelo mental mais simples | HA, autoescalonamento, atualizações são DIY (mais trabalho) |
| Kubernetes com Flink Kubernetes Operator | Maioria das equipes de plataforma modernas | Média | Implantações declarativas; gerenciamento de ciclo de vida via loop de controle; operador suporta implantações de Aplicativo/Sessão/Trabalho | Conhecimento de Kubernetes + operador necessário |
| Kubernetes nativo (sem operador) | Equipes de K8s que querem integração direta | Média–Alta | Integração direta de recursos; alocação/desalocação dinâmica de TaskManager descrita na documentação Flink-on-K8s | Automação mais personalizada que o operador |
| YARN | Plataformas centradas em Hadoop | Média | Integra-se com gerenciamento de recursos do YARN | Complexidade da pilha Hadoop |
| AWS Managed Service for Apache Flink | Pilhas de dados nativas da AWS | Baixa–Média | Orquestração gerenciada + opções de escalonamento; unidade de faturamento previsível (KPU) | Acoplamento de plataforma; sobrecarga extra de KPU por app + taxas de armazenamento |
| Confluent Cloud for Apache Flink | Empresas focadas em Kafka, apps de stream SQL-first | Baixa | Faturamento de uso serverless; contabilidade CFU-minuto; pools de computação para limitar gastos | Custos de CFU + custos de rede do Kafka; APIs específicas do serviço |
| Ofertas gerenciadas da Ververica | Empresas que precisam de operações expert em Flink | Baixa–Média | Posicionamento de serviço gerenciado de “especialistas em Flink” | Preço frequentemente não transparente (não especificado) |
Tabela de provedores gerenciados e custos
Os preços mudam por região e tempo; se você precisa de números exatos para sua região, trate isso como um ponto de partida e verifique contra as páginas de preços atuais do provedor (regiões não cotadas são não especificadas).
| Provedor | Formato do “Plano” | Unidade de faturamento | Exemplo de preço de computação | Impulsionadores de custos adicionais notáveis |
|---|---|---|---|---|
| Amazon Managed Service for Apache Flink | Runtime gerenciado | KPU (1 vCPU + 4 GB) | Exemplo mostrado: US$ 0,11 por KPU-hora (US East N. Virginia) | +1 KPU de orquestração por app; armazenamento em execução; backups duráveis opcionais |
| Confluent Cloud for Apache Flink | SQL/serverless/processing | CFU-minuto/CFU-hora | Exemplo mostrado: US$ 0,21 por CFU-hora (varia por região) | Taxas de rede do Kafka ainda se aplicam; máximo de pool de computação para limitar gastos |
| Ververica (gerenciado) | Gerenciado “Plataforma de Dados de Streaming Unificada” | Não especificado (páginas públicas) | Não especificado | Recursos de plataforma/SLAs; preço geralmente via vendas (não especificado) |
| Aiven for Apache Flink | Serviço gerenciado | Modelo de faturamento de uso por hora (plataforma-wide) | Não especificado sem plano/região | Nível do plano + região de nuvem + add-ons (não especificado) |
| Alibaba Cloud Realtime Compute for Apache Flink | Gerenciado/serverless | Faturamento híbrido (pay-as-you-go + mix de assinatura) | Não especificado sem detalhes de região/workspace | Limites baseados em CU e modelo de workspace (detalhes variam; não especificado aqui) |
Comparação Apache Flink vs concorrentes
O Flink está em um ecossistema movimentado. A “melhor” escolha depende de latência, estado, preferências operacionais e modelo de autoria.
Tabela de comparação de concorrentes: Flink vs Spark vs Kafka Streams vs Beam e opções mais novas
| Ferramenta | O que é | Modelo de execução de streaming | História de estado e exatamente-uma vez | Onde brilha | Pontos de dor típicos |
|---|---|---|---|---|---|
| Apache Flink | Motor de processamento de fluxo distribuído para computações com estado | Streaming contínuo + tempo de evento via marcas d’água | Tolerância a falhas baseada em checkpoint; savepoints para atualizações controladas | Pipelines com estado de baixa latência; lógica complexa de tempo de evento | Operar estado, checkpoints e atualizações corretamente requer disciplina |
| Apache Spark Structured Streaming | Motor de streaming do Spark construído em torno de DataFrames/Datasets | Modelo de micro-lote padrão (com um modo contínuo discutido separadamente) | Forte para pipelines analíticos; estado existe mas geralmente maior latência | APIs unificadas de lote+stream; ecossistema Spark | Latência de micro-lote e modelo mental de “streaming como lotes incrementais” |
| Kafka Streams | Biblioteca para construir aplicativos de processamento de fluxo no Kafka | Processamento registro-a-registro | Suporta semânticas de processamento exatamente-uma vez (EOS) | Aplicativos nativos do Kafka simples; incorporar em serviço JVM | Apenas JVM; menos flexível para padrões de computação distribuída em larga escala |
| Apache Beam | Modelo de programação unificado + SDKs; executado via runners (Flink, Spark, Dataflow, etc.) | Depende do runner; pipelines Beam traduzem para trabalhos do runner | Semânticas dependem da matriz de capacidade do runner (específico do runner) | Portabilidade, pipelines multi-linguagem; evitar lock-in de motor | Ajuste operacional ainda acaba sendo específico do runner |
| Materialize | “Camada de dados ao vivo” / DB SQL de streaming; atualiza resultados incrementalmente conforme os dados chegam | Manutenção incremental contínua de visualizações | Afirmações fortes de consistência na documentação do produto (detalhes são específicos do produto) | Servir visualizações derivadas frescas para apps/agentes de IA | Modelo operacional diferente de trabalhos Flink; não é um runtime de API de operador geral |
| RisingWave | Banco de dados de streaming onde o processamento de fluxo é expresso como visualizações materializadas | Manutenção contínua de visualizações materializadas | Primeiro em SQL; semânticas específicas do motor | Aplicativos de streaming centrados em SQL sem construir trabalhos Flink | Menos flexível para pipelines arbitrários pesados em código |
Um heurística útil: se você quer um runtime para trabalhos de streaming com estado complexos com controle profundo sobre tempo de evento, lógica de operador e implantações, o Flink é um candidato principal. Se você quer visualizações incrementais primeiro em SQL para servir, bancos de dados de streaming podem ser alternativas. Se você quer uma biblioteca incorporada em um serviço, Kafka Streams é competitivo. Se você quer uma definição de pipeline portátil entre motores, o Beam é atraente.
Para arquiteturas orientadas a eventos nativas na nuvem usando AWS, Construindo Microserviços Orientados a Eventos com AWS Kinesis cobre padrões de Kinesis Data Streams para processamento em tempo real e desacoplamento de serviços.
Como usar Apache Flink em sistemas personalizados
Esta seção é intencionalmente prática: configuração, implantação e como seus serviços Go/Python interagem tipicamente com o Flink.
Padrão de arquitetura recomendado: serviços Go + Kafka + Flink + camada de serviço

O Flink é frequentemente o “meio com estado” que transforma eventos de alto volume em sinais duráveis (contadores, sessões, anomalias, registros enriquecidos). Checkpoints e backends de estado são o que tornam esse meio confiável em produção.
Exemplo de configuração standalone para Apache Flink 2.x
Nota importante de versão: a partir do Flink 2.0, o arquivo de configuração suportado é conf/config.yaml; o anterior flink-conf.yaml é “não mais suportado”.
Um conf/config.yaml mínimo (ilustrativo) para um pequeno cluster auto-gerenciado:
# conf/config.yaml (estilo Flink 2.x)
rest:
address: flink-jobmanager.example.internal
port: 8081
jobmanager:
rpc:
address: flink-jobmanager.example.internal
port: 6123
memory:
process:
size: 2048m
taskmanager:
memory:
process:
size: 4096m
numberOfTaskSlots: 2
parallelism:
default: 2
# Padrões de checkpointing (trabalhos ainda podem sobrescrever no código)
state:
backend:
type: rocksdb
execution:
checkpointing:
dir: s3://my-bucket/flink/checkpoints
savepoint-dir: s3://my-bucket/flink/savepoints
interval: 60 s
# Evite diretórios temporários que são purgados (arquivos RocksDB, jars em cache, etc.)
io:
tmp:
dirs: ["/var/lib/flink/tmp"]
Por que essas chaves: a referência de configuração do Flink documenta explicitamente os detalhes de descoberta rest.* e jobmanager.rpc.*, as chaves de memória do processo, as chaves de slot/paralelismo e as configurações padrão de checkpoint, incluindo state.backend.type, execution.checkpointing.dir, execution.checkpointing.savepoint-dir e execution.checkpointing.interval.
A escolha de io.tmp.dirs é operacionalmente importante porque o Flink o usa para arquivos locais do RocksDB e artefatos em cache; excluí-lo pode causar recuperação pesada.
Exemplo de configuração standalone legado para Flink 1.x
Se você estiver no Flink 1.x (ainda comum em alguns ambientes gerenciados), verá flink-conf.yaml na natureza. Isso é legado para usuários do Flink 2.x.
# conf/flink-conf.yaml (estilo legado 1.x; NÃO suportado no Flink 2.x)
jobmanager.rpc.address: flink-jobmanager
rest.port: 8081
taskmanager.numberOfTaskSlots: 2
parallelism.default: 2
# Chaves de checkpoint legado diferem por versão; trate como ilustrativo.
state.backend.type: rocksdb
state.checkpoints.dir: s3://my-bucket/flink/checkpoints
state.savepoints.dir: s3://my-bucket/flink/savepoints
Se você estiver migrando, o Flink fornece um script de migração (bin/migrate-config-file.sh) para converter flink-conf.yaml para config.yaml.
Implantação Kubernetes/Helm com o Flink Kubernetes Operator
O Flink Kubernetes Operator atua como um plano de controle para o gerenciamento de ciclo de vida de aplicativos Flink e é instalado usando Helm.
A partir da documentação oficial do Helm do operador, você pode instalar do chart da árvore de fonte ou do repositório de charts hospedado pela Apache:
# instalar do chart incluído na árvore de fonte
helm install flink-kubernetes-operator helm/flink-kubernetes-operator
# instalar do repositório Helm de downloads da Apache (substitua <OPERATOR-VERSION>)
helm repo add flink-operator-repo https://downloads.apache.org/flink/flink-kubernetes-operator-<OPERATOR-VERSION>/
helm install flink-kubernetes-operator flink-operator-repo/flink-kubernetes-operator
Esses comandos exatos são mostrados na documentação de instalação do Helm do operador.
Exemplo de CR FlinkDeployment (ilustrativo)
Este é um exemplo simplificado para mostrar os pontos de integração que você geralmente personaliza (imagem, recursos, locais de checkpoint, logs/métricas). O operador reconcilia esse estado desejado via seu loop de controle.
apiVersion: flink.apache.org/v1beta1
kind: FlinkDeployment
metadata:
name: realtime-sessions
namespace: flink
spec:
image: my-registry.example.com/flink/realtime-sessions:2026-03-06
flinkVersion: v2_2
serviceAccount: flink
flinkConfiguration:
taskmanager.numberOfTaskSlots: "2"
state.backend.type: "rocksdb"
execution.checkpointing.dir: "s3://my-bucket/flink/checkpoints/realtime-sessions"
execution.checkpointing.savepoint-dir: "s3://my-bucket/flink/savepoints/realtime-sessions"
execution.checkpointing.interval: "60 s"
rest.port: "8081"
jobManager:
resource:
cpu: 1
memory: "2048m"
taskManager:
resource:
cpu: 2
memory: "4096m"
job:
jarURI: local:///opt/flink/usrlib/realtime-sessions.jar
parallelism: 4
upgradeMode: savepoint
state: running
O padrão upgradeMode: savepoint é comum quando você quer atualizações com estado seguras; savepoints são projetados para fluxos de trabalho de parar/retomar/bifurcar/atualizar e apontam para locais de armazenamento estável.
Desenvolvimento PyFlink: trabalho de streaming Kafka realista com checkpoints e estado RocksDB
O PyFlink é a API Python para Apache Flink e é explicitamente comercializado para cargas de trabalho de lote/stream escaláveis, incluindo pipelines de ML e ETL.
Empacotamento de dependências para trabalhos PyFlink Kafka
Quando você usa conectores JVM (Kafka, JDBC, etc.) do PyFlink, você deve garantir que os JARs relevantes estejam disponíveis para o trabalho. A documentação de “Gerenciamento de Dependências” do Flink Python mostra três mecanismos padrão:
Definir pipeline.jars (Table API), chamar add_jars() (DataStream API) ou CLI --jarfile no momento da submissão.
Exemplo de trabalho PyFlink Kafka (API DataStream + tempo de evento + estado + checkpointing)
Este exemplo lê eventos JSON do Kafka, atribui carimbos de tempo de evento (com desordem limitada), mantém uma contagem rolante por usuário em estado chaveado e escreve um evento enriquecido em um tópico de saída.
Notas:
- KafkaSource é construído via
KafkaSource.builder()e requer servidores bootstrap, tópicos e um desserializador. - A configuração de sink Kafka exatamente-uma vez no PyFlink requer definir garantia de entrega e um prefixo de ID transacional.
- Os padrões de checkpoint podem ser configurados na configuração do Flink (
execution.checkpointing.*) e/ou no código; as chaves de configuração estão documentadas na referência de configuração do Flink.
import json
from typing import Any
from pyflink.common import Duration, Types
from pyflink.common.serialization import SimpleStringSchema
from pyflink.common.watermark_strategy import WatermarkStrategy, TimestampAssigner
from pyflink.common.configuration import Configuration
from pyflink.datastream import StreamExecutionEnvironment
from pyflink.datastream.functions import KeyedProcessFunction, RuntimeContext
from pyflink.datastream.state import ValueStateDescriptor
from pyflink.datastream.connectors import DeliveryGuarantee
from pyflink.datastream.connectors.kafka import (
KafkaSource,
KafkaOffsetsInitializer,
KafkaSink,
KafkaRecordSerializationSchema,
)
class EventTimeFromJson(TimestampAssigner):
"""
Extrai event_time_ms da carga útil JSON.
Espera: {"user_id":"u1","event_time_ms":1710000000000,"event":"click",...}
"""
def extract_timestamp(self, value: str, record_timestamp: int) -> int:
try:
obj = json.loads(value)
return int(obj["event_time_ms"])
except Exception:
# fallback: usar carimbo de registro (ingestão) se malformado
return record_timestamp
class RollingCount(KeyedProcessFunction):
def open(self, runtime_context: RuntimeContext):
desc = ValueStateDescriptor("rolling_count", Types.LONG())
self.count_state = runtime_context.get_state(desc)
def process_element(self, value: str, ctx: 'KeyedProcessFunction.Context'):
obj = json.loads(value)
current = self.count_state.value()
if current is None:
current = 0
current += 1
self.count_state.update(current)
# emitir evento enriquecido
obj["rolling_count"] = current
obj["event_time_ms"] = int(obj.get("event_time_ms", 0))
yield json.dumps(obj)
def build_env() -> StreamExecutionEnvironment:
# Padrões de cluster/trabalho (também podem ser definidos em config.yaml)
cfg = Configuration()
cfg.set_string("state.backend.type", "rocksdb")
cfg.set_string("execution.checkpointing.dir", "s3://my-bucket/flink/checkpoints/realtime-sessions")
cfg.set_string("execution.checkpointing.interval", "60 s")
env = StreamExecutionEnvironment.get_execution_environment(cfg)
# No PyFlink, jars de conector devem estar disponíveis; use env.add_jars(...) se necessário.
# env.add_jars("file:///opt/flink/lib/flink-connector-kafka-<VERSION>.jar")
# Habilitar checkpointing explicitamente também (trabalhos podem sobrescrever padrões)
env.enable_checkpointing(60_000)
env.set_parallelism(4)
return env
def main():
env = build_env()
source = (
KafkaSource.builder()
.set_bootstrap_servers("kafka:9092")
.set_topics("events.raw")
.set_group_id("realtime-sessions-v1")
.set_value_only_deserializer(SimpleStringSchema())
.set_starting_offsets(KafkaOffsetsInitializer.earliest())
.build()
)
watermark_strategy = (
WatermarkStrategy.for_bounded_out_of_orderness(Duration.of_seconds(10))
.with_timestamp_assigner(EventTimeFromJson())
)
stream = (
env.from_source(source, watermark_strategy=watermark_strategy, source_name="kafka-events-raw")
.key_by(lambda s: json.loads(s)["user_id"])
.process(RollingCount(), output_type=Types.STRING())
)
record_serializer = (
KafkaRecordSerializationSchema.builder()
.set_topic("events.enriched")
.set_value_serialization_schema(SimpleStringSchema())
.build()
)
sink = (
KafkaSink.builder()
.set_bootstrap_servers("kafka:9092")
.set_record_serializer(record_serializer)
.set_delivery_guarantee(DeliveryGuarantee.EXACTLY_ONCE)
.set_transactional_id_prefix("realtime-sessions-txn")
.build()
)
stream.sink_to(sink)
env.execute("realtime-sessions-pyflink")
if __name__ == "__main__":
main()
As chamadas de API acima estão alinhadas com o padrão de uso do construtor KafkaSource do PyFlink e campos necessários.
Para garantias de entrega, a documentação KafkaSinkBuilder do PyFlink diz explicitamente que para DeliveryGuarantee.EXACTLY_ONCE você deve definir o prefixo de ID transacional.
Para carimbo de tempo/marca d’água, a documentação de marca d’água do Flink explica a atribuição de carimbo de tempo e geração de marca d’água como o mecanismo para processar tempo de evento, e o PyFlink fornece uma API WatermarkStrategy espelhando este modelo.
Integração Go: produtor/consumidor Kafka + submissão de trabalho Flink REST
Go não tem uma API nativa de autoria de trabalho Flink como Java/Python, então sistemas Go geralmente integram com Flink através de:
- Kafka (ou outros corretores) como ingestão/egresso.
- A API REST do Flink para ações operacionais (upload de JARs, iniciar trabalhos, consultar status do trabalho, acionar savepoints, redimensionar).
Para setup de Kafka e padrões de desenvolvimento local, veja Apache Kafka Quickstart - Instalar Kafka 4.2 com CLI e Exemplos Locais.
Exemplo de produtor/consumidor Go Kafka (kafka-go)
package main
import (
"context"
"log"
"time"
"github.com/segmentio/kafka-go"
)
func main() {
ctx := context.Background()
// Produtor: escrever eventos brutos
writer := &kafka.Writer{
Addr: kafka.TCP("kafka:9092"),
Topic: "events.raw",
RequiredAcks: kafka.RequireAll,
}
defer writer.Close()
err := writer.WriteMessages(ctx, kafka.Message{
Key: []byte("user:u1"),
Value: []byte(`{"user_id":"u1","event_time_ms":1710000000000,"event":"click"}`),
Time: time.Now(),
})
if err != nil {
log.Fatal(err)
}
// Consumidor: ler eventos enriquecidos
reader := kafka.NewReader(kafka.ReaderConfig{
Brokers: []string{"kafka:9092"},
Topic: "events.enriched",
GroupID: "go-debug-consumer",
MinBytes: 1e3,
MaxBytes: 10e6,
})
defer reader.Close()
msg, err := reader.ReadMessage(ctx)
if err != nil {
log.Fatal(err)
}
log.Printf("enriched key=%s value=%s\n", string(msg.Key), string(msg.Value))
}
Este é código de “encanamento”, mas é a superfície de integração prática mais comum: tópicos Kafka são a fronteira entre Flink e serviços personalizados.
API REST do Flink: upload e execução de trabalhos a partir do Go
A API REST do Flink faz parte do servidor web do JobManager e escuta na porta 8081 por padrão (configurável via rest.port).
A especificação OpenAPI oficial para o dispatcher inclui /jars/upload e afirma explicitamente:
- O upload de JAR deve ser enviado como dados multi-part
- garanta que o cabeçalho
Content-Typeesteja definido comoapplication/x-java-archive - fornece um exemplo curl usando
-F jarfile=@caminho/para/flink-job.jar
Um trecho prático Go para upload de JAR:
package flink
import (
"bytes"
"context"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func UploadJar(ctx context.Context, flinkBaseURL, jarPath string) (*http.Response, error) {
f, err := os.Open(jarPath)
if err != nil {
return nil, err
}
defer f.Close()
var body bytes.Buffer
w := multipart.NewWriter(&body)
part, err := w.CreateFormFile("jarfile", "job.jar")
if err != nil {
return nil, err
}
if _, err := io.Copy(part, f); err != nil {
return nil, err
}
if err := w.Close(); err != nil {
return nil, err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, flinkBaseURL+"/jars/upload", &body)
if err != nil {
return nil, err
}
// Importante: boundary multipart
req.Header.Set("Content-Type", w.FormDataContentType())
// Alguns clientes também definem "Expect:" similarmente ao exemplo curl na especificação.
req.Header.Set("Expect", "")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode >= 300 {
return resp, fmt.Errorf("upload failed: %s", resp.Status)
}
return resp, nil
}
Este código é guiado pela descrição OpenAPI da API REST para /jars/upload, incluindo seu requisito multipart e referência curl.
Para executar um JAR previamente carregado, o Flink expõe /jars/{jarid}/run e suporta passagem de argumentos de programa via parâmetros de consulta (e/ou corpo JSON).
Endpoints operacionalmente valiosos que você provavelmente automatizará:
/jobse/jobs/{jobid}para listar e inspecionar estado do trabalho/jobs/{jobid}/savepointspara acionar savepoints (acionador assíncrono + polling)/jobs/{jobid}/rescalingpara acionar redimensionamento
Tabela de comparação de trechos de código: PyFlink vs Go em uma plataforma baseada em Flink
| Preocupação | PyFlink (trabalhos Python) | Go (serviços ao redor do Flink) |
|---|---|---|
| Autoria de lógica Flink | Autoria nativa via APIs DataStream/Table; suporta estado + temporizadores | Nenhuma API Flink nativa; implementar lógica no Flink (Java/Python) e integrar externamente |
| Conectores/dependências | Deve enviar JARs de conector via pipeline.jars, add_jars ou --jarfile |
Não aplicável (você não está rodando dentro do Flink), mas você gerencia clientes Kafka/DB |
| Ingestão/egresso | Construtores KafkaSource/KafkaSink no PyFlink | Bibliotecas produtor/consumidor Kafka; padrões de microserviço padrão |
| Automação de Ops | Pode chamar endpoints REST do Flink também | Frequentemente possui automação: upload JAR, deploy, redimensionar, acionar savepoint via REST |
Guia DevOps: monitoramento, escalonamento, backups e CI/CD para Apache Flink
Monitoramento do Apache Flink em Kubernetes e em VMs
O Flink suporta exportação de métricas configurando reporters de métricas no arquivo de configuração do Flink; esses reporters são instanciados no JobManager e nos TaskManagers.
Para Prometheus, o Flink expõe métricas no formato Prometheus quando configurado com metrics.reporter.prom.factory.class: org.apache.flink.metrics.prometheus.PrometheusReporterFactory em um ambiente de versão Flink suportada.
Geralmente você combina isso com Kubernetes ServiceMonitors (Prometheus Operator) ou com sua pilha de monitoramento gerenciada.
Escalonamento: paralelismo, slots e autoescalonamento baseado em operador
O modelo de agendamento do Flink define recursos de execução via slots de tarefa, e cada slot pode rodar um pipeline de tarefas paralelas.
Para escalonamento manual, a API REST fornece um endpoint de redimensionamento para um trabalho (/jobs/{jobid}/rescaling) como uma operação assíncrona.
Se você estiver no Kubernetes com o Flink Kubernetes Operator, o projeto do operador anuncia um “Flink Job Autoscaler” como parte de seu conjunto de recursos, o que vale a pena avaliar se suas cargas de trabalho variam substancialmente.
Backups e atualizações seguras: checkpoints e savepoints
Checkpoints são para recuperação automatizada e são gerenciados pelo Flink; savepoints são para operações de ciclo de vida dirigidas pelo usuário (parar/retomar/bifurcar/atualizar).
De um ponto de vista SRE:
- Use checkpoints para “manter o pipeline rodando através de falhas”.
- Use savepoints para “implantar uma nova versão sem perder estado”.
A API REST do Flink também suporta acionar savepoints assincronamente, o que é útil para fluxos de trabalho estilo GitOps “deploy → acionar savepoint → atualizar”.
CI/CD: GitOps + Helm + submissão de trabalho REST
Para Kubernetes:
- Mantenha a instalação do operador e seus CRs FlinkDeployment no Git, implante via Argo CD/Flux e versionamento de imagens de container por build. A documentação do Helm do operador discute explicitamente “Trabalhando com Argo CD”.
Para clusters independentes/sessão:
- Use os endpoints de upload e execução de JAR da API REST do Flink para implantações de artefatos imutáveis.
Observe também um toggle de segurança/ops sutil, mas valioso: web.submit.enable governa uploads via Interface Web, mas a documentação observa que mesmo quando desabilitado, clusters de sessão ainda aceitam submissões de trabalho através de solicitações REST; isso é relevante ao endurecer superfícies de UI enquanto mantém automação de CI/CD.
Padrões de integração LLM/IA com Apache Flink para pipelines em tempo real
Sistemas de LLM são frequentemente tão bons quanto seu contexto em tempo real. O Flink se encaixa em pilhas de LLM/IA como o componente que produz recursos, embeddings e agregados comportamentais “sempre frescos”.
Pipeline de embeddings em tempo real com Flink
Um padrão comum é:
- ingerir ações/eventos de usuários,
- agregar sessões e preferências,
- produzir tarefas de geração de embeddings,
- escrever embeddings em um vetor store e/ou feature store.
A documentação de gerenciamento de dependências do PyFlink cita explicitamente “previsão de aprendizado de máquina” e carregamento de modelos de ML dentro de UDFs Python (para execução de cluster remoto), o que mapeia diretamente para abordagens de “inferência online dentro de operadores Flink”.
Atualizações de feature store online para recomendação e ranking
O modelo de estado chaveado e checkpointing do Flink é construído para manter estado do operador através de eventos e recuperá-lo com confiabilidade. Isso é uma correspondência natural para computação contínua de recursos (taxas rolantes, contagens, métricas com decaimento temporal) que recomendadores downstream precisam.
Compensações práticas de latência/consistência para pipelines de IA
Se sua arquitetura requer semânticas exatamente-uma vez de ponta a ponta (ex: evitar atualizações duplicadas de recursos ou eventos de faturamento duplicados), você estruturará sinks e fontes ao redor de checkpointing e garantias transacionais.
Em pilhas baseadas em Kafka especificamente:
- O conector Kafka do Flink pode entregar garantias exatamente-uma vez quando o checkpointing está habilitado e as opções de garantia de entrega estão configuradas.
- Kafka Streams também suporta semânticas exatamente-uma vez (EOS), o que é relevante se seu “pipeline de recursos de IA” for pequeno o suficiente para viver dentro do código do aplicativo em vez de um cluster Flink.
Visão de arquitetura para “Flink como construtor de contexto de IA em tempo real”

Este diagrama é fundamentado nos primitivos centrais do Flink: processamento de tempo de evento (marcas d’água), backends de estado (state.backend.type e estado local gerenciado pelo sistema) e mecanismos de checkpoint/savepoint para tolerância a falhas e operações.