Apache Flink en K8s y Kafka: PyFlink, Go, operaciones y precios gestionados
Streaming con estado, puntos de control, K8s, PyFlink, Go.
Apache Flink es un marco para computaciones con estado sobre flujos de datos acotados y no acotados.
Los equipos lo adoptan para transmisión (streaming) correcta y de baja latencia con semántica de tiempo de evento (marcadores de tiempo), tolerancia a fallos (puntos de control), actualizaciones controladas (puntos de guardado) y superficies operativas (métricas y REST).

Esta guía está dirigida a equipos de DevOps y desarrolladores de Go/Python. Compara los modelos de implementación (autoadministrado vs. gestionado), explica la arquitectura central, cubre configuraciones de Kubernetes (Helm y Operador) e implementaciones independientes, contrasta Flink con Spark, Kafka Streams, Beam y bases de datos de streaming, y muestra patrones de integración de PyFlink y Go, incluidas las tuberías orientadas a LLM e IA.
Para obtener un contexto más amplio sobre patrones de infraestructura de datos, incluido el almacenamiento de objetos, bases de datos y mensajería, consulte Infraestructura de datos para sistemas de IA: Almacenamiento de objetos, bases de datos, búsqueda y arquitectura de datos de IA.
¿Qué es Apache Flink y por qué los equipos lo utilizan para el procesamiento en tiempo real
Apache Flink se posiciona explícitamente como un motor de procesamiento de flujos con estado: modela tu lógica como una tubería de operadores y Flink la ejecuta como un flujo de datos distribuido con estado gestionado y semántica de tiempo. En la documentación moderna de Flink, el proyecto se describe como un marco y motor de procesamiento distribuido para computaciones con estado sobre flujos de datos acotados y no acotados.
Desde una perspectiva práctica de ingeniería de software/DevOps, Flink es una buena opción cuando necesitas al menos una de estas propiedades:
Si necesitas uniones/agregaciones/enriquecimiento con baja latencia y garantías de corrección, típicamente utilizas el procesamiento de tiempo de evento de Flink, donde el “tiempo” es cuándo ocurrió el evento (no cuándo llegó), y los marcadores de tiempo comunican el progreso del tiempo de evento a través de la tubería.
Si necesitas computación con estado a gran escala (contadores rodantes, sesiones, reglas de fraude, ingeniería de características), Flink trata el estado como una parte de primera clase del modelo de programación y lo hace tolerante a fallos mediante puntos de control.
Si necesitas streaming operativamente robusto (fallos, actualizaciones rodantes, reinicios), Flink realiza puntos de control del estado y las posiciones del flujo para que el trabajo pueda recuperarse y continuar con la misma semántica “como una ejecución libre de fallos”.
Casos de uso típicos para equipos de DevOps, Go, Python e IA
Flink se utiliza ampliamente para “tuberías de datos y ETL”, “análisis de streaming” y “aplicaciones impulsadas por eventos” (las categorías utilizadas por la documentación de Flink).
Para un stack de DevOps + Go/Python, los patrones típicos son los siguientes:
Un servicio Go produce eventos en Kafka; Flink consume esos eventos, realiza un procesamiento con estado (por ejemplo, deduplicación, agregación con ventana, enriquecimiento) y luego escribe los hechos derivados de nuevo en Kafka o una base de datos. Los mecanismos de operadores y puntos de control de Flink existen para hacer que estas tuberías con estado sean seguras para producción.
Para equipos de ML/LLM, PyFlink llama explícitamente a escenarios como “predicción de aprendizaje automático” y la carga de modelos de aprendizaje automático dentro de UDFs de Python como una motivación de gestión de dependencias, lo que es un respaldo directo de los patrones de “trabajo de Flink como tiempo de ejecución de inferencia en línea / ingeniería de características”.
Arquitectura y características centrales de Apache Flink
Arquitectura de clúster de Apache Flink para implementaciones en producción
El tiempo de ejecución de Flink consiste en dos tipos de procesos: JobManager y TaskManagers. La documentación enfatiza que los clientes envían el flujo de datos al JobManager; el cliente puede luego desconectarse (modo independiente) o mantenerse conectado (modo unido).
El JobManager coordina la ejecución distribuida: programación, reacción a la finalización/fallo de tareas, coordinación de puntos de control y coordinación de la recuperación. Internamente, incluye: ResourceManager (ranuras/recursos), Dispatcher (REST + Interfaz web + creación de JobMaster por trabajo) y JobMaster (gestiona un trabajo).
Los TaskManagers ejecutan los operadores/tareas e intercambian/amortiguan los flujos de datos. La unidad de programación más pequeña es la ranura de tarea; múltiples operadores pueden ejecutarse en una sola ranura (la concatenación de operadores y el uso compartido de ranuras afectan esto).
Concatenación de operadores y ranuras de tarea para el control de rendimiento y costos
Flink concatena subtareas de operadores en tareas, donde cada tarea se ejecuta mediante un solo hilo. Esto se describe como una optimización de rendimiento que reduce la sobrecarga de transferencia de hilos y amortiguamiento, aumentando el rendimiento y disminuyendo la latencia.
Las ranuras son importantes operativamente porque son la unidad de programación de recursos/aislamiento. Flink señala que cada TaskManager puede tener una o más ranuras de tarea; la asignación de ranuras reserva memoria gestionada por ranura, pero no aísla la CPU.
Procesamiento de tiempo de evento, marcadores de tiempo y datos tardíos
Flink admite múltiples nociones de tiempo: tiempo de evento, tiempo de ingesta, tiempo de procesamiento y utiliza marcadores de tiempo para modelar el progreso en el tiempo de evento.
Para trabajar con el tiempo de evento, Flink necesita asignar marcas de tiempo a los eventos y generar marcadores de tiempo; la documentación oficial “Generación de marcadores de tiempo” explica la asignación de marcas de tiempo y la generación de marcadores de tiempo como los bloques de construcción centrales, siendo WatermarkStrategy la forma estándar de configurar estrategias comunes.
Tolerancia a fallos: puntos de control versus puntos de guardado en sistemas reales
Los puntos de control existen porque “cada función y operador en Flink pueden tener estado”; el estado debe ser controlado para volverse tolerante a fallos. Los puntos de control permiten la recuperación tanto del estado como de las posiciones del flujo para que la ejecución pueda reanudarse con semántica libre de fallos.
Flink es muy explícito en que los puntos de guardado son “una imagen coherente del estado de ejecución de un trabajo de streaming, creada mediante el mecanismo de puntos de control de Flink”, utilizada para detener y reanudar, bifurcar o actualizar trabajos. Los puntos de guardado residen en almacenamiento estable (por ejemplo, HDFS, S3).
La página oficial “Puntos de control vs. Puntos de guardado” enmarca la diferencia como copias de seguridad versus registros de recuperación: los puntos de control son frecuentes, ligeros y gestionados por Flink para recuperación de fallos; los puntos de guardado son gestionados por el usuario y se utilizan para operaciones controladas como actualizaciones.
Opciones de implementación de Apache Flink y planes de precios
Opción gratuita/autoadministrada de Apache Flink
El tiempo de ejecución de Flink de código abierto es “gratis” en el sentido de la licencia, pero en producción pagas por la infraestructura y el esfuerzo operativo.
Flink está diseñado para integrarse con administradores de recursos comunes (por ejemplo, YARN y Kubernetes) y también puede ejecutarse como un clúster independiente o como una biblioteca.
Factores de costos autoadministrados para Apache Flink
Los costos de computación y memoria están impulsados por JobManager y TaskManagers, y por tu configuración de paralelismo/ranuras. La documentación de configuración de Flink cita explícitamente jobmanager.memory.process.size, taskmanager.memory.process.size, taskmanager.numberOfTaskSlots y parallelism.default como controles centrales para configuraciones distribuidas.
El disco local es un costo oculto frecuente para trabajos con estado. Flink señala que io.tmp.dirs almacena datos locales, incluidos archivos de RocksDB, resultados intermedios derramados y JARs en caché; si se borran estos datos, pueden forzar “una operación de recuperación pesada”, por lo que deberían residir en almacenamiento que no se purga periódicamente.
El costo de almacenamiento de objetos/archivos duraderos está impulsado por los directorios de puntos de control/guardado. En la configuración de Flink 2.x, los puntos de control y puntos de guardado se configuran mediante execution.checkpointing.dir y execution.checkpointing.savepoint-dir y aceptan URIs como s3://… o hdfs://….
Planes de Apache Flink gestionados y modelos de facturación típicos
Los servicios gestionados reducen el costo operativo pero añaden tarifas de plataforma y restricciones. Los detalles dependen del proveedor.
Amazon Managed Service for Apache Flink factura por KPUs (1 vCPU + 4 GB de memoria por KPU) y cobra por duración y número de KPUs en incrementos de un segundo. AWS también cobra un KPU de “orquestración” adicional por aplicación y tarifas separadas de almacenamiento/copias de seguridad.
Confluent Cloud for Apache Flink es basado en uso y sin servidor: creas un grupo de computación y se te factura por CFUs consumidos por minuto mientras se ejecutan las declaraciones. La página de facturación incluye un precio de ejemplo de CFU de $0.21 por CFU-hora (dependiente de la región) y enfatiza que puedes limitar el gasto mediante máximos del grupo de computación.
Aiven y Alibaba Cloud son proveedores gestionados de Flink notables en el mercado, pero sus detalles de precios públicos y facturación varían según el plan/región y pueden requerir calculadoras o contacto con ventas; trata los costos exactos como no especificados a menos que solicites una cotización de región+plan de su documentación actual.
Ververica ofrece opciones de implementación autoadministradas y gestionadas alrededor de Flink; las páginas públicas enfatizan las opciones de implementación y posicionamiento de servicio gestionado, mientras que los precios exactos suelen manejarse mediante flujos de “contacto/detalles de precios” (por lo que los números específicos suelen estar no especificados públicamente).
Tabla de opciones de implementación de Apache Flink en producción
| Opción de implementación | Mejor para | Complejidad operativa | Beneficios clave | Riesgos clave / compensaciones |
|---|---|---|---|---|
| Clúster independiente (VMs/hardware sin servidor) | Equipos pequeños, capacidad fija | Media–Alta | Control total; modelo mental más simple | HA, escalado automático, actualizaciones son DIY (más trabajo manual) |
| Kubernetes con Flink Kubernetes Operator | La mayoría de los equipos de plataformas modernas | Media | Implementaciones declarativas; gestión del ciclo de vida mediante bucle de control; el operador soporta implementaciones de Aplicación/Sesión/Trabajo | Se requiere experiencia en Kubernetes + operador |
| Kubernetes nativo (sin operador) | Equipos de K8s que buscan integración directa | Media–Alta | Integración directa de recursos; asignación/desasignación dinámica de TaskManager descrita en la documentación de Flink-on-K8s | Automatización más específica que el operador |
| YARN | Plataformas centradas en Hadoop | Media | Se integra con la gestión de recursos de YARN | Complejidad del stack de Hadoop |
| AWS Managed Service for Apache Flink | Pila de datos nativa de AWS | Baja–Media | Orquestación gestionada + opciones de escalado; unidad de facturación predecible (KPU) | Acoplamiento a la plataforma; KPU de sobrecarga adicional por aplicación + tarifas de almacenamiento |
| Confluent Cloud for Apache Flink | Empresas centradas en Kafka, aplicaciones de streaming SQL-first | Baja | Facturación de uso sin servidor; contabilidad de CFU-minuto; grupos de computación para limitar el gasto | Costos de CFU + costos de red de Kafka; APIs específicas del servicio |
| Ofrecimientos gestionados de Ververica | Empresas que necesitan operaciones expertas de Flink | Baja–Media | Posicionamiento de servicio gestionado con “expertos en Flink” | Los precios a menudo no son transparentes (no especificados) |
Tabla de proveedores gestionados y costos
Los precios cambian según la región y el tiempo; si necesitas números exactos para tu región, trata esto como un punto de partida y verifica contra las páginas de precios actuales del proveedor (las regiones no citadas están no especificadas).
| Proveedor | Forma del “Plan” | Unidad de facturación | Precio de computación de ejemplo | Factores de costos adicionales notables |
|---|---|---|---|---|
| Amazon Managed Service for Apache Flink | Tiempo de ejecución gestionado | KPU (1 vCPU + 4 GB) | Ejemplo mostrado: $0.11 por KPU-hora (US East N. Virginia) | +1 KPU de orquestación por aplicación; almacenamiento en ejecución; copias de seguridad duraderas opcionales |
| Confluent Cloud for Apache Flink | SQL/Procesamiento sin servidor | CFU-minuto/CFU-hora | Ejemplo mostrado: $0.21 por CFU-hora (la región varía) | Las tarifas de red de Kafka siguen aplicándose; máximo del grupo de computación para limitar el gasto |
| Ververica (gestionado) | “Plataforma de datos de streaming unificada” gestionada | No especificado (páginas públicas) | No especificado | Características de plataforma/SLAs; precios típicamente vía ventas (no especificado) |
| Aiven for Apache Flink | Servicio gestionado | Modelo de facturación de uso por hora (plataforma completa) | No especificado sin plan/región | Nivel del plan + región en la nube + complementos (no especificado) |
| Alibaba Cloud Realtime Compute for Apache Flink | Gestionado/sin servidor | Facturación híbrida (pago por uso + mezcla de suscripción) | No especificado sin detalles de región/espacio de trabajo | Límites basados en CU y modelo de espacio de trabajo (los detalles varían; no especificado aquí) |
Comparativa de Apache Flink frente a competidores
Flink se encuentra en un ecosistema ocupado. La “mejor” elección depende de la latencia, el estado, las preferencias operativas y el modelo de autoría.
Tabla de comparación de competidores: Flink vs Spark vs Kafka Streams vs Beam y opciones más nuevas
| Herramienta | Qué es | Modelo de ejecución de streaming | Historia de estado y exactamente-una vez | Dónde brilla | Puntos de dolor típicos |
|---|---|---|---|---|---|
| Apache Flink | Motor de procesamiento de flujos distribuido para computaciones con estado | Streaming continuo + tiempo de evento mediante marcadores de tiempo | Tolerancia a fallos basada en puntos de control; puntos de guardado para actualizaciones controladas | Tuberías con estado de baja latencia; lógica compleja de tiempo de evento | Operar el estado, puntos de control y actualizaciones correctamente requiere disciplina |
| Apache Spark Structured Streaming | Motor de streaming de Spark construido alrededor de DataFrames/Datasets | Modelo de micro-lotes por defecto (con un modo continuo discutido por separado) | Fuerte para tuberías analíticas; el estado existe pero a menudo tiene mayor latencia | APIs unificadas de lote+streaming; ecosistema de Spark | Latencia de micro-lotes y modelo mental de “streaming como lotes incrementales” |
| Kafka Streams | Biblioteca para crear aplicaciones de procesamiento de flujos en Kafka | Procesamiento registro a registro | Soporta semántica de procesamiento exactamente-una vez (EOS) | Aplicaciones nativas de Kafka simples; incrustado en servicio JVM | Solo JVM; menos flexible para patrones de computación distribuida a gran escala |
| Apache Beam | Modelo de programación unificado + SDKs; ejecutado mediante runners (Flink, Spark, Dataflow, etc.) | Depende del runner; las tuberías de Beam se traducen a trabajos del runner | La semántica depende de la matriz de capacidades del runner (específica del runner) | Portabilidad, tuberías multilingües; evitar el bloqueo del motor | El ajuste operativo sigue siendo específico del runner |
| Materialize | “Capa de datos en vivo” / BD SQL de streaming; actualiza resultados incrementalmente a medida que llegan los datos | Mantenimiento continuo de vistas incrementales | Reivindicaciones de consistencia fuerte en la documentación del producto (los detalles son específicos del producto) | Servir vistas derivadas frescas a aplicaciones/agentes de IA | Modelo operativo diferente a los trabajos de Flink; no es un tiempo de ejecución de API de operador general |
| RisingWave | Base de datos de streaming donde el procesamiento de flujos se expresa como vistas materializadas | Mantenimiento continuo de vistas materializadas | Primero SQL; semántica específica del motor | Aplicaciones de streaming centradas en SQL sin construir trabajos de Flink | Menos flexible para tuberías arbitrarias pesadas en código |
Una heurística útil: si quieres un tiempo de ejecución para trabajos de streaming con estado complejos con un control profundo sobre el tiempo de evento, la lógica de operadores y las implementaciones, Flink es un candidato principal. Si quieres vistas incrementales primero en SQL para servir, las bases de datos de streaming pueden ser alternativas. Si quieres una biblioteca incrustada en un servicio, Kafka Streams es competitivo. Si quieres una definición de tubería portable entre motores, Beam es convincente.
Para arquitecturas impulsadas por eventos nativas en la nube que utilizan AWS, Construcción de microservicios impulsados por eventos con AWS Kinesis cubre patrones de Kinesis Data Streams para procesamiento en tiempo real y desacoplamiento de servicios.
Cómo usar Apache Flink en sistemas personalizados
Esta sección es intencionalmente práctica: configuración, implementación y cómo tus servicios de Go/Python interactúan típicamente con Flink.
Patrón de arquitectura recomendado: servicios Go + Kafka + Flink + capa de servicio

Flink suele ser el “medio con estado” que convierte eventos de alto volumen en señales duraderas (contadores, sesiones, anomalías, registros enriquecidos). Los puntos de control y los backends de estado son lo que hacen que ese medio sea fiable en producción.
Ejemplo de configuración independiente para Apache Flink 2.x
Nota importante de versión: a partir de Flink 2.0, el archivo de configuración admitido es conf/config.yaml; el anterior flink-conf.yaml ya no está “soportado”.
Un conf/config.yaml mínimo (ilustrativo) para un pequeño clúster autoadministrado:
# 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
# Valores predeterminados de puntos de control (los trabajos aún pueden sobrescribir en el código)
state:
backend:
type: rocksdb
execution:
checkpointing:
dir: s3://my-bucket/flink/checkpoints
savepoint-dir: s3://my-bucket/flink/savepoints
interval: 60 s
# Evita directorios tmp que se purgen (archivos RocksDB, JARs en caché, etc.)
io:
tmp:
dirs: ["/var/lib/flink/tmp"]
¿Por qué estas claves: la referencia de configuración de Flink documenta explícitamente los detalles de descubrimiento de rest.* y jobmanager.rpc.*, las claves de memoria de proceso, las claves de ranura/paralelismo y la configuración predeterminada de puntos de control, incluido state.backend.type, execution.checkpointing.dir, execution.checkpointing.savepoint-dir y execution.checkpointing.interval.
La elección de io.tmp.dirs es operativamente importante porque Flink lo utiliza para archivos locales de RocksDB y artefactos en caché; borrarlo puede causar una recuperación pesada.
Ejemplo de configuración independiente antigua para Flink 1.x
Si estás en Flink 1.x (aún común en algunos entornos gestionados), verás flink-conf.yaml en el mundo real. Esto es legado para usuarios de Flink 2.x.
# conf/flink-conf.yaml (estilo antiguo 1.x; NO soportado en Flink 2.x)
jobmanager.rpc.address: flink-jobmanager
rest.port: 8081
taskmanager.numberOfTaskSlots: 2
parallelism.default: 2
# Las claves de puntos de control antiguos difieren según la versión; trátalo como ilustrativo.
state.backend.type: rocksdb
state.checkpoints.dir: s3://my-bucket/flink/checkpoints
state.savepoints.dir: s3://my-bucket/flink/savepoints
Si estás migrando, Flink proporciona un script de migración (bin/migrate-config-file.sh) para convertir flink-conf.yaml a config.yaml.
Implementación de Kubernetes/Helm con el Operador de Kubernetes de Flink
El Operador de Kubernetes de Flink actúa como plano de control para la gestión del ciclo de vida de aplicaciones de Flink y se instala usando Helm.
Desde la documentación oficial de Helm del operador, puedes instalar desde el árbol de fuentes del gráfico o desde el repositorio de gráficos alojado por Apache:
# instalar desde el gráfico empaquetado en el árbol de fuentes
helm install flink-kubernetes-operator helm/flink-kubernetes-operator
# instalar desde el repositorio de Helm de descargas de Apache (reemplaza <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
Estos comandos exactos se muestran en la documentación de instalación de Helm del operador.
Ejemplo de CR FlinkDeployment (ilustrativo)
Este es un ejemplo simplificado para mostrar los puntos de integración que típicamente personalizarás (imagen, recursos, ubicaciones de puntos de control, registro/métricas). El operador reconcilia este estado deseado mediante su bucle de control.
apiVersion: flink.apache.org/v1beta1
kind: FlinkDeployment
metadata:
name: sesiones-tiempo-real
namespace: flink
spec:
image: my-registry.example.com/flink/sesiones-tiempo-real:2026-03-06
flinkVersion: v2_2
serviceAccount: flink
flinkConfiguration:
taskmanager.numberOfTaskSlots: "2"
state.backend.type: "rocksdb"
execution.checkpointing.dir: "s3://my-bucket/flink/checkpoints/sesiones-tiempo-real"
execution.checkpointing.savepoint-dir: "s3://my-bucket/flink/savepoints/sesiones-tiempo-real"
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/sesiones-tiempo-real.jar
parallelism: 4
upgradeMode: savepoint
state: running
El patrón upgradeMode: savepoint es común cuando quieres actualizaciones con estado seguras; los puntos de guardado están diseñados para flujos de trabajo de detener/reanudar/bifurcar/actualizar y apuntan a ubicaciones de almacenamiento estables.
Desarrollo de PyFlink: trabajo de streaming de Kafka realista con puntos de control y estado RocksDB
PyFlink es la API de Python para Apache Flink y se ofrece explícitamente para cargas de trabajo de lote/streaming escalables, incluidas tuberías de ML y ETL.
Empaquetado de dependencias para trabajos de Kafka de PyFlink
Cuando utilizas conectores de JVM (Kafka, JDBC, etc.) desde PyFlink, debes asegurarte de que los JARs relevantes estén disponibles para el trabajo. La documentación de “Gestión de dependencias” de Python de Flink muestra tres mecanismos estándar:
Establecer pipeline.jars (API Table), llamar a add_jars() (API DataStream) o CLI --jarfile en el momento de la presentación.
Ejemplo de trabajo de Kafka de PyFlink (API DataStream + tiempo de evento + estado + puntos de control)
Este ejemplo lee eventos JSON de Kafka, asigna marcas de tiempo de tiempo de evento (con desorden acotado), mantiene un conteo rodante por usuario en estado clave y escribe un evento enriquecido en un tema de salida.
Notas:
- KafkaSource se construye mediante
KafkaSource.builder()y requiere servidores bootstrap, temas y un deserializador. - La configuración de sumidero de Kafka exactamente-una vez en PyFlink requiere establecer la garantía de entrega y un prefijo de ID transaccional.
- Los valores predeterminados de puntos de control se pueden configurar en la configuración de Flink (
execution.checkpointing.*) y/o en el código; las claves de configuración están documentadas en la referencia de configuración de 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):
"""
Extraer event_time_ms de la carga útil JSON.
Esperado: {"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:
# respaldo: usar marca de tiempo del registro (ingesta) si está 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:
# Valores predeterminados de clúster/trabajo (también se pueden establecer en config.yaml)
cfg = Configuration()
cfg.set_string("state.backend.type", "rocksdb")
cfg.set_string("execution.checkpointing.dir", "s3://my-bucket/flink/checkpoints/sesiones-tiempo-real")
cfg.set_string("execution.checkpointing.interval", "60 s")
env = StreamExecutionEnvironment.get_execution_environment(cfg)
# En PyFlink, los JARs del conector deben estar disponibles; usa env.add_jars(...) si es necesario.
# env.add_jars("file:///opt/flink/lib/flink-connector-kafka-<VERSION>.jar")
# Habilitar puntos de control explícitamente también (los trabajos pueden sobrescribir valores predeterminados)
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("sesiones-tiempo-real-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("sesiones-tiempo-real-txn")
.build()
)
stream.sink_to(sink)
env.execute("sesiones-tiempo-real-pyflink")
if __name__ == "__main__":
main()
Las llamadas a API anteriores coinciden con el patrón de uso del constructor KafkaSource de PyFlink y los campos requeridos.
Para garantías de entrega, la documentación de KafkaSinkBuilder de PyFlink dice explícitamente que para DeliveryGuarantee.EXACTLY_ONCE debes establecer el prefijo de ID transaccional.
Para marcas de tiempo/marcadores de tiempo, la documentación de marcadores de tiempo de Flink explica la asignación de marcas de tiempo y la generación de marcadores de tiempo como el mecanismo para procesar el tiempo de evento, y PyFlink proporciona una API WatermarkStrategy que refleja este modelo.
Integración de Go: productor/consumidor de Kafka + presentación de trabajos de Flink REST
Go no tiene una API de autoría de trabajos de Flink nativa como Java/Python, por lo que los sistemas de Go típicamente se integran con Flink a través de:
- Kafka (u otros brokers) como ingesta/salida.
- La API REST de Flink para acciones operativas (carga de JARs, inicio de trabajos, consulta de estado del trabajo, disparo de puntos de guardado, reescalado).
Para la configuración de Kafka y patrones de desarrollo local, consulte Inicio rápido de Apache Kafka - Instalación de Kafka 4.2 con CLI y ejemplos locales.
Ejemplo de productor/consumidor de Kafka de Go (kafka-go)
package main
import (
"context"
"log"
"time"
"github.com/segmentio/kafka-go"
)
func main() {
ctx := context.Background()
// Productor: escribir eventos crudos
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: leer 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 es código de “plomería”, pero es la superficie de integración práctica más común: los temas de Kafka son la frontera entre Flink y servicios personalizados.
API REST de Flink: cargar y ejecutar trabajos desde Go
La API REST de Flink es parte del servidor web del JobManager y escucha en el puerto 8081 por defecto (configurable vía rest.port).
La especificación OpenAPI oficial para el dispatcher incluye /jars/upload y establece explícitamente:
- La carga de JAR debe enviarse como datos multi-parte
- asegúrate de que el encabezado
Content-Typese establezca enapplication/x-java-archive - proporciona un ejemplo de curl usando
-F jarfile=@path/to/flink-job.jar
Un fragmento de Go práctico para cargar un 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: límite multi-parte
req.Header.Set("Content-Type", w.FormDataContentType())
// Algunos clientes también establecen "Expect:" similar al ejemplo de curl en la especificación.
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 está guiado por la descripción OpenAPI de la API REST para /jars/upload, incluido su requisito multi-parte y referencia curl.
Para ejecutar un JAR previamente cargado, Flink expone /jars/{jarid}/run y admite pasar argumentos del programa mediante parámetros de consulta (y/o cuerpo JSON).
Endpoints operativamente valiosos que probablemente automatizarás:
/jobsy/jobs/{jobid}para listar e inspeccionar el estado del trabajo/jobs/{jobid}/savepointspara activar puntos de guardado (disparo asíncrono + sondeo)/jobs/{jobid}/rescalingpara activar reescalado
Tabla de comparación de fragmentos de código: PyFlink vs Go en una plataforma basada en Flink
| Preocupación | PyFlink (trabajos de Python) | Go (servicios alrededor de Flink) |
|---|---|---|
| Autoría de lógica de Flink | Autoría nativa mediante APIs DataStream/Table; soporta estado + temporizadores | Sin API nativa de Flink; implementar lógica en Flink (Java/Python) e integrar externamente |
| Conectores/dependencias | Debes enviar JARs del conector vía pipeline.jars, add_jars o --jarfile |
No aplicable (no estás ejecutando dentro de Flink), pero gestionas clientes de Kafka/DB |
| Ingesta/salida | Constructores KafkaSource/KafkaSink en PyFlink | Bibliotecas de productor/consumidor de Kafka; patrones estándar de microservicios |
| Automatización de operaciones | También puede llamar a endpoints REST de Flink | A menudo posee la automatización: cargar JAR, implementar, reescalar, activar punto de guardado vía REST |
Guía de DevOps: monitoreo, escalado, copias de seguridad y CI/CD para Apache Flink
Monitoreo de Apache Flink en Kubernetes y en VMs
Flink admite la exportación de métricas configurando reportadores de métricas en el archivo de configuración de Flink; estos reportadores se instancian en JobManager y TaskManagers.
Para Prometheus, Flink expone métricas en formato Prometheus cuando se configura con metrics.reporter.prom.factory.class: org.apache.flink.metrics.prometheus.PrometheusReporterFactory en un entorno de versión de Flink admitido.
Generalmente combinas esto con ServiceMonitors de Kubernetes (Operador de Prometheus) o con tu stack de monitoreo gestionado.
Escalado: paralelismo, ranuras y escalado automático basado en operadores
El modelo de programación de Flink define recursos de ejecución mediante ranuras de tarea, y cada ranura puede ejecutar una tubería de tareas paralelas.
Para el escalado manual, la API REST proporciona un endpoint de reescalado para un trabajo (/jobs/{jobid}/rescaling) como una operación asíncrona.
Si estás en Kubernetes con el Operador de Kubernetes de Flink, el proyecto del operador anuncia un “Escalador automático de trabajos de Flink” como parte de su conjunto de características, lo cual vale la pena evaluar si tus cargas de trabajo varían sustancialmente.
Copias de seguridad y actualizaciones seguras: puntos de control y puntos de guardado
Los puntos de control son para recuperación automatizada y son gestionados por Flink; los puntos de guardado son para operaciones de ciclo de vida impulsadas por el usuario (detener/reanudar/bifurcar/actualizar).
Desde una perspectiva de SRE:
- Utiliza puntos de control para “mantener la tubería en ejecución a través de fallos”.
- Utiliza puntos de guardado para “desplegar una nueva versión sin perder el estado”.
La API REST de Flink también admite activar puntos de guardado de forma asíncrona, lo cual es útil para flujos de trabajo de estilo GitOps “desplegar → activar punto de guardado → actualizar”.
CI/CD: GitOps + Helm + presentación de trabajos REST
Para Kubernetes:
- Mantén la instalación del operador y tus CRs de FlinkDeployment en Git, despliega mediante Argo CD/Flux y versiona las imágenes de contenedor por compilación. La documentación de Helm del operador discute explícitamente “Trabajar con Argo CD”.
Para clústeres independientes/sesión:
- Utiliza los endpoints de carga y ejecución de JAR de la API REST de Flink para implementaciones de artefactos inmutables.
También nota un interruptor de seguridad/operaciones sutil pero valioso: web.submit.enable gobierna las cargas a través de la interfaz web, pero la documentación señala que incluso cuando está deshabilitado, los clústeres de sesión siguen aceptando presentaciones de trabajos a través de solicitudes REST; esto es relevante al endurecer superficies de UI mientras se retiene la automatización de CI/CD.
Patrones de integración de LLM/IA con Apache Flink para tuberías en tiempo real
Los sistemas de LLM a menudo son tan buenos como su contexto en tiempo real. Flink encaja en los stacks de LLM/IA como el componente que produce características, incrustaciones y agregados conductuales “siempre frescos”.
Tubería de incrustaciones en tiempo real con Flink
Un patrón común es:
- ingerir acciones/eventos de usuarios,
- agregar sesiones y preferencias,
- producir tareas de generación de incrustaciones,
- escribir incrustaciones en un almacén vectorial y/o almacén de características.
La documentación de gestión de dependencias de PyFlink cita explícitamente “predicción de aprendizaje automático” y la carga de modelos de ML dentro de UDFs de Python (para ejecución en clúster remoto), lo cual mapea directamente a enfoques de “inferencia en línea dentro de operadores de Flink”.
Actualizaciones de almacén de características en línea para recomendación y clasificación
El modelo de estado clave y puntos de control de Flink está construido para mantener el estado del operador a través de eventos y recuperarlo de manera fiable. Eso es una coincidencia natural para la computación continua de características (tasas rodantes, conteos, métricas de decaimiento temporal) que los recomendadores posteriores necesitan.
Compensaciones prácticas de latencia/consistencia para tuberías de IA
Si tu arquitectura requiere semántica exactamente-una vez de extremo a extremo (por ejemplo, evitar actualizaciones de características duplicadas o eventos de facturación duplicados), estructurarás sumideros y fuentes alrededor de puntos de control y garantías transaccionales.
En stacks basados en Kafka específicamente:
- El conector de Kafka de Flink puede ofrecer garantías exactamente-una vez cuando se habilitan los puntos de control y se configuran las opciones de garantía de entrega.
- Kafka Streams también soporta semántica exactamente-una vez (EOS), lo cual es relevante si tu “tubería de características de IA” es lo suficientemente pequeña para vivir dentro del código de la aplicación en lugar de un clúster de Flink.
Vista de arquitectura para “Flink como constructor de contexto de IA en tiempo real”

Este diagrama se basa en los primitivos centrales de Flink: procesamiento de tiempo de evento (marcadores de tiempo), backends de estado (state.backend.type y estado local gestionado por el sistema) y mecanismos de puntos de control/guardado para tolerancia a fallos y operaciones.