Apache Flink FLIP-13: Mejorando el Procesamiento de Datos

Apache Flink FLIP-13: Mejorando el Procesamiento de Datos

«`html

Apache Flink FLIP-13: Salidas Laterales para un Procesamiento de Datos Más Flexible

El mundo del procesamiento de datos en tiempo real presenta desafíos únicos, especialmente cuando se trata de gestionar flujos de datos que requieren un tratamiento diferenciado. En este contexto, el concepto de salidas laterales (Side Outputs) en Apache Flink surge como una solución innovadora. Esta funcionalidad permite manejar distintos tipos de datos de manera más eficiente, evitando cuellos de botella en el procesamiento y mejorando la flexibilidad en la gestión de flujos de datos.

Imagina una cinta transportadora donde los paquetes deben ser clasificados en diferentes salidas. Tradicionalmente, un operario solo puede enviar paquetes a una única salida. Si se encuentra con paquetes dañados, tiene que parar la cinta o deshacerse de ellos, lo que claramente no es lo suficientemente flexible. Las salidas laterales resuelven este problema, permitiendo que diferentes tipos de datos se dirijan a distintas salidas según las necesidades.

¿Por qué necesitamos salidas laterales?

En el procesamiento de flujos de datos en la vida real, a menudo se presentan situaciones como:

  • Datos corruptos que bloquean el ciclo de procesamiento.
  • Datos que llegan tarde y que, de no ser gestionados adecuadamente, deben ser descartados.

Antes de la implementación de las salidas laterales, gestionar estas situaciones era problemático. Por ejemplo, cuando los datos se corrompían, la tarea completa podía entrar en un ciclo de «fallo -> reinicio -> fallo nuevamente». Por otro lado, los datos que llegaban tarde solo podían ser descartados, lo que resultaba en una pérdida de información valiosa.

Solución: Instalación de «Divisores de Flujo» en los Operadores

El diseño de las salidas laterales se asemeja a la instalación de un «divisor de flujo» en cada operador, lo que permite que diferentes tipos de datos se envíen a diferentes flujos. Este diseño incluye dos conceptos clave:

  • OutputTag: Se utiliza para marcar y distinguir diferentes flujos de salida.
  • CollectorWrapper: Envuelve el colector, permitiendo la salida de datos a diferentes flujos.

Comparación de Escenarios

La siguiente tabla resume la comparación entre el enfoque tradicional y el uso de salidas laterales:

EscenarioEnfoque TradicionalUso de Salidas Laterales
Gestión de Datos CorruptosParar tarea o descartarSalida a flujo de manejo de errores dedicado
Procesamiento de Datos TardíosDebido a descartarSalida a flujo de procesamiento tardío
Clasificación de DatosRequiere múltiples tareas separadasDivisión de flujo en una única tarea
Depuración y MonitoreoDificultad para rastrear tipos de datos específicosRecolección separada de datos de interés

Ejemplo de Uso

A continuación, se presenta un ejemplo de procesamiento de datos de pedidos, mostrando cómo utilizar las salidas laterales para gestionar diferentes situaciones:

    // Definir etiquetas de salida
    final OutputTag invalidOrders = new OutputTag("invalid-orders") {};
    final OutputTag lateOrders = new OutputTag("late-orders") {};

    // Procesar flujo de pedidos
    SingleOutputStreamOperator mainStream = orderStream
        .process(new ProcessFunction() {
            @Override
            public void processElement(Order order, Context ctx, Collector out) {
                // Verificar validez del pedido
                if (!order.isValid()) {
                    // Salida de pedidos inválidos a salida lateral
                    ctx.output(invalidOrders, order);
                    return;
                }
                
                // Verificar tiempo del pedido
                if (order.getTimestamp() < ctx.timerService().currentWatermark()) {
                    // Salida de pedidos tardíos a salida lateral
                    ctx.output(lateOrders, order);
                    return;
                }
                
                // Salida de pedidos normales al flujo principal
                out.collect(order);
            }
        });

    // Obtener y procesar flujo de pedidos inválidos
    DataStream invalidOrderStream = mainStream.getSideOutput(invalidOrders);
    invalidOrderStream.addSink(new InvalidOrderHandler());

    // Obtener y procesar flujo de pedidos tardíos
    DataStream lateOrderStream = mainStream.getSideOutput(lateOrders);
    lateOrderStream.addSink(new LateOrderHandler());
    

Implementación Interna

Las salidas laterales utilizan un diseño ingenioso:

  • Etiquetas de Salida: Cada flujo de salida lateral tiene una etiqueta de salida única.
  • Colector Envuelto: Utiliza CollectorWrapper para envolver el colector original.
  • Seguridad de Tipo: OutputTag extiende TypeHint, garantizando la seguridad de tipo.
  • Distinguir en Tiempo de Ejecución: Utiliza etiquetas para distinguir diferentes flujos de salida y dirigir a los destinos correctos.

Estado Actual

Esta funcionalidad ha sido implementada en Flink y se utiliza ampliamente en la actualidad. Su implementación se realizó en dos fases:

  • La primera fase mantuvo la compatibilidad hacia atrás, añadiendo principalmente la interfaz RichCollector.
  • La segunda fase implicó una reestructuración más profunda del marco para admitir escenarios de múltiples salidas más flexibles.

Conclusión

Las salidas laterales añaden una capacidad de procesamiento de datos más flexible a Flink, similar a agregar múltiples salidas a una cinta transportadora. Esta mejora simplifica el procesamiento de datos, eliminando la preocupación de que datos defectuosos causen fallos en tareas completas y evitando la necesidad de abandonar datos que lleguen tarde. A través de un diseño API simple, los usuarios pueden implementar fácilmente lógica compleja de transmisión de datos, haciendo que todo el flujo de procesamiento de datos sea más claro y eficiente.

Fuente: Alibaba Cloud

«`

Deja una respuesta