Todos los productos
Search
Centro de documentos

Realtime Compute for Apache Flink:Flink CDC UDFs

Última actualización: Sep 03, 2026

Aprenda a crear, registrar y usar funciones definidas por el usuario (UDF) de Java en trabajos de Flink CDC. Cuando las funciones integradas no satisfacen sus necesidades, las UDF personalizadas ofrecen formas flexibles de ampliar las capacidades de procesamiento de datos.

Funciones definidas por el usuario (UDF)

Si las funciones integradas de Flink CDC no cubren su lógica de transformación de datos (por ejemplo, cifrar o descifrar campos, analizar formatos de datos personalizados o invocar una biblioteca de terceros), escriba una UDF de Java e invoquela como cualquier otra función integrada.

El flujo de trabajo general consta de tres pasos:

  1. Definir: Escriba una clase de Java que implemente la interfaz de la UDF.

  2. Registrar: Declare la UDF en la sección pipeline de la configuración de su trabajo de Flink CDC.

  3. Usar: Invoque la UDF en las expresiones de projection y filter dentro de un bloque transform.

Definir una UDF de Java

Para escribir una UDF en Java, primero cree un proyecto de Maven y agregue la siguiente dependencia base a su archivo pom.xml:

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-cdc-common</artifactId>
    <version>${Apache Flink CDC version}</version>
    <scope>provided</scope>
</dependency>

Seleccione la versión de Apache Flink CDC que corresponda a la versión de su motor Ververica Runtime (VVR):

Versión del motor VVR

Versión de Apache Flink CDC

11.7 y posteriores

3.6.0

11.3 a 11.6

3.5.0

11.0 a 11.2

3.4.0

8.0.11

3.3.0

8.0.10 y anteriores

3.2.1

Una clase de Java debe cumplir los siguientes requisitos para funcionar como una UDF de Flink CDC:

  • Implementar la interfaz org.apache.flink.cdc.common.udf.UserDefinedFunction

  • Tener un constructor público sin parámetros

  • Tener como mínimo un método público llamado eval

De forma opcional, puede sobrescribir los siguientes métodos para obtener mayor control:

  • getReturnType: Especifique explícitamente el tipo de retorno cuando eval tenga un tipo de retorno ambiguo.

  • open y close: Agregue lógica de inicialización y limpieza para la gestión del ciclo de vida.

El siguiente ejemplo define una UDF que incrementa un número entero en 1:

public class AddOneFunctionClass implements UserDefinedFunction {

    public Object eval(Integer num) {
        return num + 1;
    }

    @Override
    public DataType getReturnType() {
        // The return type of eval is ambiguous (Object).
        // Use getReturnType to declare the exact CDC type.
        return DataTypes.INT();
    }

    @Override
    public void open() throws Exception {
        // Initialize resources here, for example, open a database connection.
    }

    @Override
    public void close() throws Exception {
        // Release resources here, for example, close a database connection.
    }
}

Mapeo de tipos

La siguiente tabla muestra la correspondencia entre los tipos de columna de CDC y los tipos de Java utilizados en los parámetros del método eval, los valores de retorno y getReturnType:

Tipo de columna CDC

Clase de Java

BOOLEAN

java.lang.Boolean

TINYINT

java.lang.Byte

SMALLINT

java.lang.Short

INTEGER

java.lang.Integer

BIGINT

java.lang.Long

FLOAT

java.lang.Float

DOUBLE

java.lang.Double

DECIMAL

java.math.BigDecimal

DATE

java.time.LocalDate

TIME

java.time.LocalTime

TIMESTAMP

java.time.LocalDateTime

TIMESTAMP_TZ

java.time.ZonedDateTime

TIMESTAMP_LTZ

java.time.Instant

CHAR / VARCHAR / STRING

java.lang.String

BINARY / VARBINARY / BYTES

byte[]

ARRAY

java.util.List (los tipos de elemento se asignan al parámetro genérico de List)

MAP

java.util.Map (los tipos de clave y valor se asignan a los parámetros genéricos de Map)

ROW

java.util.List

VARIANT

org.apache.flink.cdc.common.types.variant.Variant

La ruta de la clase VARIANT difiere de la ruta de la clase Variant en Flink SQL.

Registrar una UDF de Java

Agregue una entrada user-defined-function a la sección pipeline de la configuración de su trabajo de Flink CDC:

pipeline:
  user-defined-function:
    - name: inc
      classpath: org.apache.flink.cdc.udf.examples.java.AddOneFunctionClass
    - name: format
      classpath: org.apache.flink.cdc.udf.examples.java.FormatFunctionClass
En la pestaña Configurations tab del borrador de su trabajo, cargue el archivo JAR correspondiente al classpath especificado como dependencia adicional en la sección More Configurations. El campo name establece el alias que se usa en las expresiones; no es necesario que coincida con el nombre de la clase.

UDF de Python (vista previa pública)

Puede escribir UDF en línea directamente en Python dentro de los trabajos de ingesta YAML de Flink CDC, sin necesidad de crear un proyecto de Maven ni compilar paquetes JAR adicionales.

Nota

Para definir UDF con Python, debe actualizar a Ververica Runtime (VVR) 11.9 (incluidas las ediciones de vista previa) o posterior.

Esta es una función experimental.

Reglas de sintaxis

Una UDF de Python debe cumplir los siguientes requisitos:

  • Se debe definir una función de nivel superior llamada eval en python-code.

  • La función eval debe declarar una anotación de tipo de retorno.

  • El número de parámetros de la función eval debe coincidir con el número de argumentos pasados al invocar la UDF.

  • Las anotaciones de tipo de parámetro no son obligatorias, pero se recomienda mantenerlas para mejorar la legibilidad del código.

  • Actualmente, las UDF de Python solo admiten funciones escalares. Cada invocación devuelve un único valor.

  • Los valores NULL de SQL en los datos de entrada se convierten a None en Python.

  • Una función de Python puede devolver None. En ese caso, la salida será NULL en SQL.

Por ejemplo, la siguiente UDF de Python elimina los espacios en blanco de la cadena de entrada y la convierte a minúsculas:

def eval(value: str) -> str:
    return value.strip().lower()

Puede definir funciones auxiliares, importar módulos o declarar constantes en python-code, pero la función eval que realiza la transformación de datos debe estar en el nivel superior del código. Por ejemplo:

import re

EMAIL_PATTERN = re.compile(r"\s+")

def normalize(value):
    return EMAIL_PATTERN.sub("", value).lower()

def eval(value: str) -> str:
    if value is None: return None
    return normalize(value)
Nota

Puede importar paquetes integrados de Python en el nivel superior del bloque de código. Para consultar la lista completa, consulte Pre-installed packages.

Mapeo de tipos

Flink CDC determina el tipo de columna de salida de una UDF según la anotación de tipo de retorno de la función eval. Actualmente, solo se admiten los siguientes tipos de parámetros y valores de retorno:

Anotación de tipo de retorno en Python

Tipo de columna CDC

bool

BOOLEAN

int

BIGINT

float

DOUBLE

str

STRING

bytes

BYTES

Registrar una UDF de Python

Para registrar una UDF de Python, configure el parámetro python-code bajo pipeline.user-defined-function en un trabajo de ingesta de Flink CDC. La sintaxis de cadena multilínea | de YAML le permite escribir bloques de código Python con sangría de forma natural:

pipeline:
  user-defined-function:
    - name: normalize_email
      python-code: |
        def eval(value: str) -> str:
            if value is None:
                return None
            return value.strip().lower()

    - name: double_age
      python-code: |
        def eval(value: int) -> int:
            if value is None:
                return None
            return value * 2

En este caso, name es el nombre de la función que se utiliza en las expresiones de transformación y no necesita coincidir con el nombre de la función de Python. La función que Flink CDC invoca en el código en línea siempre es eval.

Manejo de valores nulos y excepciones en UDF de Python

Los valores NULL en un pipeline de ingesta corresponden a None en Python. Si se invoca una UDF con un argumento NULL, la función eval de Python recibe None. Si la función eval de Python devuelve None, se utiliza NULL como valor de retorno de la UDF.

Si la función eval de Python genera una excepción en tiempo de ejecución, el operador de transformación desencadena un failover. Si existe la posibilidad de que su UDF falle, capture las excepciones mediante instrucciones try/except de Python para mantener la estabilidad del trabajo.

Parámetros de UDF de Python

Las UDF de Python admiten los siguientes parámetros.

Parámetro

Descripción

Obligatorio

Tipo de dato

Valor predeterminado

Observaciones

name

Nombre de la UDF registrada en el módulo de transformación.

Sí

STRING

Ninguna

Los nombres de las UDF deben ser únicos dentro de un mismo trabajo.

python-code

Código fuente en línea de la UDF de Python.

Sí

STRING

Ninguna

Debe contener una función de nivel superior llamada eval con una anotación de tipo de retorno compatible declarada.

python-files

Dependencias adicionales utilizadas por la UDF de Python.

No

LIST<STRING>

Ninguna

Si una UDF de Python requiere dependencias adicionales, empaquételas en un archivo .zip y cárguelo como dependencia adicional.

Nota

Los archivos de dependencias adicionales se colocan en el directorio /flink/usrlib/. Introduzca la ruta completa incluyendo el prefijo.

Por ejemplo, si el archivo de dependencia adicional es PIL.zip, configure la ruta completa /flink/usrlib/PIL.zip.

Usar una UDF

Después de registrar una UDF, puede invocarla directamente en el bloque de transformación, igual que una función integrada:

transform:
  - source-table: db\.*
    projection: "*, inc(inc(inc(id))) as inc_id, format(id, 'id -> %d') as formatted_id"
    filter: inc(id) < 100

Compatibilidad con UDF de Flink SQL

Las UDF de Flink SQL que extienden ScalarFunction pueden registrarse e invocarse directamente como UDF de Flink CDC. Se aplican las siguientes limitaciones:

  • Parametrización: No se admiten clases ScalarFunction parametrizadas.

  • Anotaciones de tipo: Las anotaciones TypeInformation al estilo de Flink se ignoran.

  • Hooks de ciclo de vida: Los hooks de ciclo de vida open y close no se invocan.