Volver al inicio

Procesamiento de datos en streaming: arquitectura en Kafka y Flink

Artículo sobre la construcción de un sistema de procesamiento de datos en streaming usando Apache Kafka, Flink y S3. Se cubren en detalle las etapas de integración, ejemplos de configuración y mejores prácticas para entornos de producción.

Construyendo un sistema de streaming como un constructor LEGO: guía práctica
Advertisement 728x90

# Procesamiento en Streaming: Arquitectura como Bloques de LEGO

Los sistemas modernos de procesamiento de datos exigen flexibilidad y escalabilidad. En este artículo, desglosaremos cómo combinar Kafka, Flink, S3 y otros componentes en una plataforma unificada de streaming utilizando principios de arquitectura modular. Profundizaremos en las etapas de integración en detalle, desde la generación de datos hasta el análisis en tiempo real.

Fundamento del Sistema: Plataforma de Streaming

Para construir el procesamiento en streaming, utilizamos una pila de tecnologías probadas y robustas. El componente central es Apache Kafka, una plataforma de streaming distribuida que garantiza la entrega confiable de mensajes. Junto a él, empleamos:

  • Kafka Connect para la integración con sistemas externos
  • Schema Registry para la gestión de esquemas de datos
  • Kafka UI como interfaz de gestión visual

La idea clave es tratar los componentes como bloques de LEGO. Cada uno maneja una función específica y se conecta a los demás mediante interfaces bien definidas. Para lanzar una configuración mínima, Docker Compose y Git LFS son todo lo que necesitas. El sistema se ensambla mediante builds multi-etapa, asegurando entornos reproducibles.

Google AdInline article slot

Ejemplo de configuración básica en docker-compose.yml:

services:
  kafka:
    image: confluentinc/cp-kafka:8.1.0
    environment:
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092

  schema-registry:
    image: confluentinc/cp-schema-registry:8.1.0
    environment:
      SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: kafka:9092

Es importante entender la diferencia entre bases de datos tradicionales y sistemas de streaming. En los SGBD relacionales, el enfoque está en el estado (tablas, registros), mientras que en el procesamiento en streaming, se centra en eventos. Cada mensaje en Kafka representa un evento inmutable que se añade al final del log. Este enfoque permite sistemas con entrega garantizada y recuperación de estado.

Etapas de Integración de Datos

Dividiremos el proceso de construcción del sistema en cuatro etapas lógicas:

Google AdInline article slot
  • Ingest — recepción de datos de fuentes externas
  • Storage — almacenamiento persistente
  • Transform — transformación y enriquecimiento
  • Serve — entrega de resultados

Ingest: Generación e Ingestión de Datos

En la etapa Ingest, configuramos la fuente de datos mediante Kafka Connect. Para la demostración, implementaremos un generador de lecturas de sensores de temperatura. El conector Java genera datos sintéticos con coordenadas geográficas y temperatura, teniendo en cuenta la hora del día y la posición relativa al ecuador.

Configuración del conector:

{
  "connector.class": "dev.miron.connect.temp.TempSourceConnector",
  "tasks.max": "1",
  "topic": "earth-temp",
  "sensors": "5",
  "messages.per.sensor.per.second": "1"
}

Nota el uso de Avro para serialización. Los mensajes se almacenan en formato binario, reduciendo el volumen de tráfico y acelerando el procesamiento. Schema Registry maneja el versionado de esquemas y las verificaciones de compatibilidad (modo BACKWARD). Cuando cambia la estructura de datos, el sistema rechaza automáticamente las actualizaciones inválidas.

Google AdInline article slot

Storage: Almacenamiento a Largo Plazo

Para el almacenamiento persistente, usamos una combinación de S3 y Apache Iceberg. S3 actúa como almacenamiento de objetos, mientras que Iceberg añade una capa de metadatos que permite transacciones ACID y viaje en el tiempo. Este enfoque maneja eficientemente grandes conjuntos de datos, evitando problemas con sistemas de archivos tradicionales.

Configuración del conector sink:

{
  "connector.class": "io.confluent.connect.s3.S3SinkConnector",
  "topics": "earth-temp",
  "s3.bucket.name": "data-lake",
  "storage.class": "io.confluent.connect.s3.storage.S3Storage",
  "format.class": "io.confluent.connect.s3.format.avro.AvroFormat"
}

Para consultas de datos, usamos Trino, un motor SQL distribuido capaz de federar datos de múltiples fuentes. Esto permite consultas analíticas complejas sin mover datos.

Transformación de Datos

Implementamos la etapa Transform con Apache Flink, un motor de procesamiento en streaming que soporta ventanas y operaciones con estado. Tarea de ejemplo: convertir temperatura de Fahrenheit a Celsius y filtrar valores anómalos.

DataStream<TempEvent> processed = source
  .map(event -> {
    event.setCelsius((event.getFahrenheit() - 32) * 5/9);
    return event;
  })
  .filter(event -> event.getCelsius() > -50 && event.getCelsius() < 60);

Flink se integra con Kafka mediante conectores nativos. Es crucial configurar correctamente el checkpointing para garantías de procesamiento exactly-once. Parámetros clave:

  • execution.checkpointing.interval: 60000
  • state.backend: rocksdb
  • state.checkpoints.dir: file:///checkpoints

Para monitoreo, usamos la interfaz web integrada de Flink para rastrear retrasos de procesamiento (lag) y estados de operadores.

Capa de Servicio

En la etapa final, los datos están disponibles para los consumidores. Implementamos dos opciones:

  • PostgreSQL mediante conector JDBC para consultas operacionales
  • Redis para caché de datos calientes

Configuración sink de PostgreSQL:

{
  "connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
  "connection.url": "jdbc:postgresql://postgres:5432/analytics",
  "topics": "processed-temp",
  "auto.create": "true",
  "insert.mode": "upsert",
  "pk.fields": "sensorId,timestamp"
}

Para Redis, usamos un conector personalizado que almacena las últimas lecturas de cada sensor en tablas hash. Esto proporciona latencia de milisegundos para consultas a datos actuales.

Puntos Clave

  • Los esquemas de datos deben gestionarse mediante Schema Registry con compatibilidad BACKWARD
  • El procesamiento con estado en Flink requiere configuración de checkpointing y selección de backend de estado
  • La descomposición del sistema en etapas Ingest/Storage/Transform/Serve simplifica la depuración
  • La serialización binaria (Avro/Protobuf) es crítica para el rendimiento de sistemas de streaming
  • Probar configuraciones mediante Docker Compose permite iteraciones rápidas

— Editorial Team

Advertisement 728x90

Leer después