Todos los productos
Search
Centro de documentos

Realtime Compute for Apache Flink:Kafka connector

Última actualización: Sep 15, 2026

Utilice el conector SQL de Kafka como tabla de origen o tabla de destino en Realtime Compute for Apache Flink.

Descripción general

Apache Kafka es una plataforma de streaming de eventos distribuida y de código abierto, muy utilizada para el procesamiento de datos de alto rendimiento, el análisis de streaming y la integración de datos. El conector de Kafka para Realtime Compute for Apache Flink utiliza el cliente de código abierto de Apache Kafka para ofrecer un alto rendimiento de transferencia de datos. Además, admite la lectura y escritura de varios formatos de datos y proporciona semántica exactly-once.

Categoría

Descripción

Tipos compatibles

Origen y destino SQL

Origen y destino Flink CDC

Origen y destino DataStream

Modo de ejecución

Streaming

Formatos de datos

Formatos de datos compatibles

  • CSV

  • JSON

  • Apache Avro

  • Confluent Avro

  • Debezium JSON

  • Canal JSON

  • Maxwell JSON

  • Raw

  • Protobuf

Nota
  • El formato de datos Protobuf integrado solo es compatible con Ververica Runtime (VVR) 8.0.9 y versiones posteriores.

  • Cada formato de datos compatible cuenta con parámetros correspondientes que se pueden especificar en la cláusula WITH. Para obtener más información, consulte Formats.

Métricas

Métricas

  • Tabla de origen

    • numRecordsIn

    • numRecordsInPerSecond

    • numBytesIn

    • numBytesInPerSecond

    • currentEmitEventTimeLag

    • currentFetchEventTimeLag

    • sourceIdleTime

    • pendingRecords

  • Tabla de destino

    • numRecordsOut

    • numRecordsOutPerSecond

    • numBytesOut

    • numBytesOutPerSecond

    • currentSendTime

Nota

Para obtener más información sobre las métricas, consulte Metrics.

Tipos de API

SQL, DataStream, Flink CDC

Actualización y eliminación en destino

El conector solo admite agregar datos a una tabla de destino. No admite actualizaciones ni eliminaciones.

Nota

Para obtener más información sobre cómo actualizar o eliminar datos en una tabla de destino, consulte Upsert Kafka.

Requisitos previos

Antes de empezar, compruebe que cumple los requisitos previos según el tipo de clúster de Kafka:

  • Conexión a un clúster de ApsaraMQ for Kafka

    • El clúster de Kafka debe ser de la versión 0.11 o posterior.

    • Creó un clúster de ApsaraMQ for Kafka. Para obtener más información, consulte Step 3: Create resources.

    • El espacio de trabajo de Flink y el clúster de Kafka deben estar en la misma Virtual Private Cloud (VPC). Además, agregó el bloque CIDR del espacio de trabajo de Flink a la lista blanca de ApsaraMQ for Kafka. Para obtener más información, consulte Configure whitelists.

    Importante

    Limitaciones para escribir datos en ApsaraMQ for Kafka:

    • ApsaraMQ for Kafka no admite el formato de compresión Zstandard (zstd) para escrituras.

    • ApsaraMQ for Kafka no admite escrituras idempotentes ni transaccionales, lo que impide usar la semántica exactly-once que proporcionan las tablas de destino de Kafka. A partir de Ververica Runtime (VVR) 8.0.0, el conector de Kafka usa el cliente de Kafka 3.x, donde la propiedad properties.enable.idempotence tiene el valor predeterminado true. Por lo tanto, para evitar errores de escritura al usar Ververica Runtime (VVR) 8.0.0 o versiones posteriores con ApsaraMQ for Kafka, debe agregar la configuración properties.enable.idempotence=false a la definición de su tabla de destino. Para consultar una comparación de los motores de almacenamiento y las limitaciones de funciones de ApsaraMQ for Kafka, consulte Comparison between storage engines.

  • Conexión a un clúster de Apache Kafka autogestionado

    • El clúster de Apache Kafka autogestionado debe ser de la versión 0.11 o posterior.

    • El espacio de trabajo de Flink debe tener conectividad de red con el clúster de Apache Kafka autogestionado. Para conocer los detalles sobre cómo conectarse a un clúster a través de Internet público, consulte FAQ about network connectivity.

    • Solo se admiten las opciones de configuración de cliente para Apache Kafka versión 2.8. Para obtener más información, consulte la documentación de Apache Kafka sobre Consumer Configs y Producer Configs.

Notas

No se recomiendan las escrituras transaccionales debido a limitaciones de diseño conocidas en Apache Flink y Apache Kafka. Cuando establece sink.delivery-guarantee = 'exactly-once', el conector de Kafka habilita las escrituras transaccionales, lo cual presenta los siguientes problemas conocidos:

  • Cada checkpoint genera un nuevo Transaction ID. Si el intervalo entre checkpoints es demasiado corto, la gran cantidad de Transaction IDs resultante puede agotar la memoria del coordinador del clúster de Kafka y comprometer su estabilidad.

  • Cada transacción crea una nueva instancia de Producer. Si se confirman demasiadas transacciones de forma simultánea, el TaskManager puede quedarse sin memoria y desestabilizar el trabajo de Apache Flink.

  • Si varios trabajos de Apache Flink usan el mismo sink.transactional-id-prefix, los Transaction IDs generados pueden entrar en conflicto. Cuando falla una operación de escritura en un trabajo, se puede impedir que avance el Log Start Offset (LSO) de una partición de Apache Kafka. Esto afecta a todos los consumidores de esa partición.

Si necesita semántica exactly-once, utilice Upsert Kafka connector para escribir en una tabla con clave primaria y así garantizar la idempotencia. Si es indispensable usar escrituras transaccionales, consulte Exactly-once semantics usage notes.

Solución de problemas de conectividad de red

Si un trabajo de Realtime Compute for Apache Flink no inicia y muestra el error Timed out waiting for a node assignment, suele indicar un problema de conectividad de red entre Realtime Compute for Apache Flink y el clúster de Kafka.

Un cliente de Kafka se conecta a los brokers mediante el siguiente proceso:

  1. El cliente usa las direcciones especificadas en bootstrap.servers para establecer una conexión inicial con el clúster de Kafka.

  2. El clúster de Kafka devuelve los metadatos de cada broker, incluidos sus endpoints.

  3. Después, el cliente usa estos endpoints para conectarse a los brokers y leer o escribir datos.

Incluso si se puede acceder a las direcciones de bootstrap.servers, el cliente no podrá leer ni escribir datos si Kafka devuelve endpoints de broker incorrectos. Este problema ocurre con frecuencia en arquitecturas de red que utilizan un proxy, reenvío de puertos o una línea dedicada.

Pasos para solucionar problemas

ApsaraMQ for Kafka

  1. Confirme el tipo de endpoint

    • Default Endpoint (red interna)

    • SASL Endpoint (red interna con autenticación)

    • Public Endpoint (requiere una solicitud por separado)

    Utilice la función Network Probe en la consola de desarrollo de Realtime Compute for Apache Flink para descartar problemas de conectividad con la dirección bootstrap.servers.

  2. Revise los security groups y las listas blancas

    Agregue el bloque CIDR del espacio de trabajo de Realtime Compute for Apache Flink a la lista blanca de su instancia de Kafka. Para obtener más información, consulte View VPC CIDR Block y Configure a whitelist.

  3. Compruebe la configuración de SASL (si está habilitada)

    Si utiliza un endpoint SASL_SSL, asegúrese de que los mecanismos JAAS, SSL y SASL estén configurados correctamente en su trabajo de Realtime Compute for Apache Flink. Sin una autenticación adecuada, la conexión puede fallar durante la fase de handshake, lo cual también podría mostrarse como un tiempo de espera agotado. Para obtener más información, consulte Security and authentication.

Self-managed Kafka

  1. Utilice la función Network Probe****

    Esta función le ayuda a descartar problemas de conectividad con la dirección bootstrap.servers y a comprobar que se utiliza el endpoint interno o público correcto.

  2. Revise los security groups y las listas blancas

    • El security group de la instancia de Elastic Compute Service (ECS) debe permitir el tráfico entrante en el puerto del endpoint de Kafka, que normalmente es el 9092 o el 9093.

    • Asegúrese de que cualquier firewall en la instancia de ECS permita el tráfico desde la VPC de su espacio de trabajo de Realtime Compute for Apache Flink. Para obtener más información, consulte View VPC CIDR Block.

  3. Compruebe la configuración

    1. Utilice la herramienta zkCli.sh o zookeeper-shell.sh para iniciar sesión en el clúster de ZooKeeper que usa Kafka.

    2. Ejecute un comando para obtener los metadatos del broker. Por ejemplo, ejecute get /brokers/ids/0. En el campo endpoints de la respuesta, busque la dirección que Kafka anuncia a los clientes.

      
      # bin/zookeeper-shell.sh localhost:2181
      Connecting to localhost:2181
      Welcome to ZooKeeper!
      JLine support is disabled
      
      WATCHER::
      
      WatchedEvent state:SyncConnected type:None path:null
      get /brokers/ids/0
      {"listener_security_protocol_map":{"PLAINTEXT":"PLAINTEXT"},"endpoints":["PLAINTEXT://116.62.xxx:9092"],"jmx_port":-1,"host":"116.62.xxx","timestamp":"1614840078030","port":9092,"version":4}
      
    3. Utilice la función Network Probe en la consola de desarrollo de Realtime Compute for Apache Flink para probar si se puede acceder a esta dirección.

      Nota
      • Si no se puede acceder a la dirección, comuníquese con los administradores de Kafka para que revisen y corrijan las configuraciones listeners y advertised.listeners. Así se asegurará de que la dirección anunciada sea accesible desde Realtime Compute for Apache Flink.

      • Para obtener más información sobre las conexiones de clientes de Kafka, consulte Troubleshoot Connectivity.

  4. Compruebe la configuración de SASL (si está habilitada)

    Si utiliza un endpoint SASL_SSL, asegúrese de que los mecanismos JAAS, SSL y SASL estén configurados correctamente en su trabajo de Realtime Compute for Apache Flink. Sin una autenticación adecuada, la conexión puede fallar durante la fase de handshake, lo cual también podría mostrarse como un tiempo de espera agotado. Para obtener más información, consulte Security and authentication.

SQL

Utilice el conector de Kafka como tabla de origen o tabla de destino en trabajos SQL.

Sintaxis

CREATE TABLE KafkaTable (
  `user_id` BIGINT,
  `item_id` BIGINT,
  `behavior` STRING,
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL
) WITH (
  'connector' = 'kafka',
  'topic' = 'user_behavior',
  'properties.bootstrap.servers' = 'localhost:9092',
  'properties.group.id' = 'testGroup',
  'scan.startup.mode' = 'earliest-offset',
  'format' = 'csv'
)

Columnas de metadatos

Defina columnas de metadatos en una tabla de origen o de destino para acceder a los metadatos de los mensajes de Kafka. Por ejemplo, cuando se suscribe a varios temas, una columna de metadatos permite identificar de qué tema proviene cada registro.

CREATE TABLE kafka_source (
  -- Read the message topic as the `record_topic` column
  `record_topic` STRING NOT NULL METADATA FROM 'topic' VIRTUAL,
  -- Read the timestamp from the ConsumerRecord as the `ts` column
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
  -- Read the message offset as the `record_offset` column
  `record_offset` BIGINT NOT NULL METADATA FROM 'offset' VIRTUAL,
  ...
) WITH (
  'connector' = 'kafka',
  ...
);

CREATE TABLE kafka_sink (
  -- Write the timestamp from the `ts` column as the ProducerRecord's timestamp to Kafka
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
  ...
) WITH (
  'connector' = 'kafka',
  ...
);

A continuación se muestran las columnas de metadatos que admiten las tablas de origen y de destino de Kafka.

Clave

Tipo

Descripción

Alcance

topic

STRING NOT NULL METADATA VIRTUAL

Tema del mensaje.

Tabla de origen

partition

INT NOT NULL METADATA VIRTUAL

ID de la partición del mensaje.

Tabla de origen

headers

MAP<STRING, BYTES> NOT NULL METADATA VIRTUAL

Encabezados del mensaje.

Tabla de origen y tabla de destino

leader-epoch

INT NOT NULL METADATA VIRTUAL

Leader-epoch del mensaje.

Tabla de origen

offset

BIGINT NOT NULL METADATA VIRTUAL

Offset del mensaje.

Tabla de origen

timestamp

TIMESTAMP(3) WITH LOCAL TIME ZONE NOT NULL METADATA VIRTUAL

Marca de tiempo del mensaje.

Tabla de origen y tabla de destino

timestamp-type

STRING NOT NULL METADATA VIRTUAL

Tipo de marca de tiempo del mensaje. Los valores válidos son:

  • NoTimestampType: no se definió ninguna marca de tiempo en el mensaje.

  • CreateTime: la hora en que se creó el mensaje.

  • LogAppendTime: la hora en que se anexó el mensaje al registro del broker de Kafka.

Tabla de origen

__raw_key__

STRING NOT NULL METADATA VIRTUAL

Clave sin procesar del mensaje.

Tabla de origen y tabla de destino

Nota

Este parámetro solo es compatible con Ververica Runtime (VVR) 11.4 y versiones posteriores.

__raw_value__

STRING NOT NULL METADATA VIRTUAL

Valor sin procesar del mensaje.

Tabla de origen y tabla de destino

Nota

Este parámetro solo es compatible con Ververica Runtime (VVR) 11.4 y versiones posteriores.

Opciones del conector

  • Generales

    Option

    Descripción

    Tipo

    Obligatorio

    Predeterminado

    Observaciones

    connector

    El tipo de conector.

    String

    Sí

    –

    El valor debe ser kafka.

    properties.bootstrap.servers

    Una lista de direcciones de brokers de Kafka.

    String

    Sí

    –

    Formato: host1:port1,host2:port2,.... Separe las direcciones con comas (,).

    properties.*

    Propiedades adicionales para el cliente de Kafka.

    String

    No

    –

    Las claves de propiedad deben ser opciones válidas definidas en la documentación oficial de Apache Kafka para Producer Configs y Consumer Configs.

    Realtime Compute for Apache Flink elimina el prefijo properties. y pasa los pares clave-valor restantes al cliente de Kafka subyacente. Por ejemplo, establezca 'properties.allow.auto.create.topics' = 'false' para deshabilitar la creación automática de temas.

    El conector de Kafka sobrescribe estas opciones, por lo que no se pueden configurar de esta manera:

    • key.deserializer

    • value.deserializer

    format

    El formato para serializar y deserializar el valor de un mensaje de Kafka.

    String

    No

    –

    Formatos compatibles:

    • csv

    • json

    • avro

    • debezium-json

    • canal-json

    • maxwell-json

    • avro-confluent

    • raw

    Nota

    Para obtener más información, consulte Opciones de formato.

    key.format

    El formato para serializar y deserializar la clave de un mensaje de Kafka.

    String

    No

    –

    Formatos compatibles:

    • csv

    • json

    • avro

    • debezium-json

    • canal-json

    • maxwell-json

    • avro-confluent

    • raw

    Nota

    Cuando utilice esta configuración, key.options es obligatorio.

    key.fields

    Los campos del esquema de la tabla que se usan como clave del mensaje de Kafka.

    String

    No

    –

    Separe varios nombres de campo con puntos y comas (;). Por ejemplo, 'field1;field2'.

    key.fields-prefix

    Un prefijo personalizado para todos los campos de clave, con el fin de evitar conflictos de nombre con los campos de valor.

    String

    No

    –

    Este prefijo distingue los campos de clave de los de valor. Se elimina antes de serializar la clave o después de deserializarla.

    Nota

    Si utiliza esta opción, value.fields-include debe establecerse en EXCEPT_KEY.

    value.format

    El formato para serializar y deserializar el valor de un mensaje de Kafka.

    String

    No

    –

    Esta configuración equivale a format. Solo puede establecer format o value.format, pero no ambos. Si configura los dos, value.format anula a format.

    value.fields-include

    Define si los campos de clave se incluyen en el formato de valor.

    String

    No

    ALL

    Valores válidos:

    • ALL: El valor del mensaje de Kafka incluye todas las columnas de la tabla.

    • EXCEPT_KEY: El valor del mensaje de Kafka incluye todas las columnas de la tabla, excepto las definidas en key.fields.

  • Tabla de origen

    Option

    Descripción

    Tipo

    Obligatorio

    Predeterminado

    Observaciones

    topic

    El tema o los temas de los que se leerá.

    String

    No

    –

    Para suscribirse a varios temas, separe sus nombres con puntos y comas (;); por ejemplo, 'topic-1;topic-2'.

    Nota

    Puede especificar esta opción o topic-pattern, pero no ambas.

    topic-pattern

    Una expresión regular que coincide con los temas a los que desea suscribirse. El consumidor se suscribe a todos los temas cuyos nombres coincidan con este patrón.

    String

    No

    –

    Ejemplos:

    • user_event_.*: Coincide con todos los temas que tienen el prefijo user_event_.

    • prod\.logs\..*: Coincide con los temas que tienen el prefijo prod.logs. (el carácter . debe escaparse).

    Nota

    Puede especificar esta opción o topic, pero no ambas.

    properties.group.id

    El ID del grupo de consumidores de origen de Kafka.

    String

    No

    KafkaSource-{Source-Table-Name}

    Si utiliza un ID de grupo de consumidores por primera vez, también debe establecer properties.auto.offset.reset en earliest o latest para definir el desplazamiento inicial de arranque.

    scan.startup.mode

    El desplazamiento de arranque del consumidor de Kafka.

    String

    No

    group-offsets

    Valores válidos:

    • earliest-offset: Comienza a leer desde el desplazamiento más antiguo disponible.

    • latest-offset: Comienza a leer desde el desplazamiento más reciente.

    • group-offsets: Comienza a leer desde los desplazamientos confirmados del properties.group.id especificado.

    • timestamp: Comienza a leer desde el scan.startup.timestamp-millis especificado.

    • specific-offsets: Comienza a leer desde los desplazamientos especificados en scan.startup.specific-offsets.

    Nota

    Esta opción solo aplica cuando un trabajo inicia sin estado. Si un trabajo se reanuda desde un checkpoint, lee desde los desplazamientos almacenados en el estado del checkpoint.

    scan.startup.specific-offsets

    El desplazamiento de inicio por partición cuando scan.startup.mode es specific-offsets.

    String

    No

    –

    Por ejemplo, partition:0,offset:42;partition:1,offset:300

    scan.startup.timestamp-millis

    La marca de tiempo de inicio en milisegundos cuando scan.startup.mode se establece en timestamp.

    Long

    No

    –

    La unidad es milisegundos.

    scan.topic-partition-discovery.interval

    El intervalo de detección de particiones.

    Duration

    No

    5 minutos

    El conector detecta periódicamente nuevas particiones y lee de ellas. Cuando utiliza topic-pattern, el conector también detecta nuevos temas que coinciden con el patrón. Establezca el intervalo en un valor no positivo para deshabilitar esta función.

    Nota

    En Ververica Runtime (VVR) 6.0.x, la detección dinámica de particiones está deshabilitada de forma predeterminada. A partir de VVR 8.0, esta función se habilita de forma predeterminada con un intervalo de detección de 5 minutos.

    scan.header-filter

    Filtra mensajes según los encabezados de los mensajes de Kafka.

    String

    No

    –

    Una clave de encabezado y su valor se separan con dos puntos (:). Varias condiciones de encabezado se conectan mediante operadores lógicos (& y |). También se admite el operador lógico NOT (!). Por ejemplo, depart:toy|depart:book&!env:test conserva los datos de Kafka si el encabezado contiene depart=toy o depart=book y no contiene env=test.

    Nota
    • Esta opción solo es compatible con Ververica Runtime (VVR) 8.0.6 y versiones posteriores.

    • No se admiten paréntesis en las expresiones.

    • Las operaciones lógicas se evalúan de izquierda a derecha.

    • Los valores de los encabezados se convierten a cadenas UTF-8 para la comparación.

    scan.check.duplicated.group.id

    Comprueba si otro consumidor activo ya está utilizando el properties.group.id.

    Boolean

    No

    false

    Valores válidos:

    • true: Antes de iniciar el trabajo, el sistema comprueba si existe un grupo de consumidores duplicado. Si encuentra uno, el trabajo falla para evitar conflictos.

    • false: Inicia el trabajo sin comprobar si hay conflictos.

    Nota

    Esta opción solo es compatible con Ververica Runtime (VVR) 6.0.4 y versiones posteriores.

  • Tabla de destino

    Option

    Descripción

    Tipo

    Obligatorio

    Predeterminado

    Observaciones

    topic

    El tema de destino.

    String

    Sí

    –

    –

    sink.partitioner

    Asigna registros de instancias de destino paralelas a particiones de Kafka.

    String

    No

    default

    Valores válidos:

    • default: Utiliza el particionador predeterminado de Kafka.

    • fixed: Cada instancia de destino paralela escribe en una partición fija de Kafka.

    • round-robin: Los registros se distribuyen entre las particiones de forma rotativa.

    • Particionador personalizado: Para usar un particionador personalizado, proporcione el nombre de clase completo de una subclase de FlinkKafkaPartitioner; por ejemplo, org.mycompany.MyPartitioner.

    sink.delivery-guarantee

    La garantía de entrega del destino.

    String

    No

    at-least-once

    Valores válidos:

    • none: No ofrece garantías. Los registros pueden perderse o duplicarse.

    • at-least-once: Garantiza que no se pierdan registros, aunque podrían duplicarse.

    • exactly-once: Utiliza transacciones de Kafka para ofrecer semántica exactly-once, lo que garantiza que los registros no se pierdan ni se dupliquen.

    Nota

    Cuando utilice la semántica exactly-once, también debe especificar sink.transactional-id-prefix.

    sink.transactional-id-prefix

    El prefijo del ID de transacción. Es obligatorio cuando sink.delivery-guarantee es exactly-once.

    String

    Sí, si sink.delivery-guarantee es exactly-once

    –

    Solo es obligatorio cuando sink.delivery-guarantee se establece en exactly-once.

    sink.parallelism

    El paralelismo del operador de destino.

    Integer

    No

    –

    De forma predeterminada, el framework determina el paralelismo según los operadores anteriores.

Seguridad y autenticación

Si el clúster de Kafka requiere una conexión segura o autenticación, agregue el prefijo properties. a las configuraciones de seguridad y autenticación correspondientes, y establézcalas en el parámetro WITH. A continuación se muestra un ejemplo donde se configura una tabla de Kafka para usar PLAIN como mecanismo SASL con una configuración JAAS.

CREATE TABLE KafkaTable (
  `user_id` BIGINT,
  `item_id` BIGINT,
  `behavior` STRING,
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp'
) WITH (
  'connector' = 'kafka',
  ...
  'properties.security.protocol' = 'SASL_PLAINTEXT',
  'properties.sasl.mechanism' = 'PLAIN',
  'properties.sasl.jaas.config' = 'org.apache.flink.kafka.shaded.org.apache.kafka.common.security.plain.PlainLoginModule required username="username" password="password";'
)

A continuación se muestra cómo utilizar SASL_SSL como protocolo de seguridad y SCRAM-SHA-256 como mecanismo SASL.

CREATE TABLE KafkaTable (
  `user_id` BIGINT,
  `item_id` BIGINT,
  `behavior` STRING,
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp'
) WITH (
  'connector' = 'kafka',
  ...
  'properties.security.protocol' = 'SASL_SSL',
  /* SSL configuration */
  /* Path to the truststore for the server's CA certificate. */
  /* Files uploaded using Artifacts are stored in the /flink/usrlib/ directory. */
  'properties.ssl.truststore.location' = '/flink/usrlib/kafka.client.truststore.jks',
  'properties.ssl.truststore.password' = 'test1234',
  /* If client authentication is required, you must also configure the path to the keystore (private key). */
  'properties.ssl.keystore.location' = '/flink/usrlib/kafka.client.keystore.jks',
  'properties.ssl.keystore.password' = 'test1234',
  /* The algorithm used to verify the server hostname. An empty string disables hostname verification. */
  'properties.ssl.endpoint.identification.algorithm' = '',
  /* SASL configuration */
  /* Set the SASL mechanism to SCRAM-SHA-256. */
  'properties.sasl.mechanism' = 'SCRAM-SHA-256',
  /* Configure JAAS. */
  'properties.sasl.jaas.config' = 'org.apache.flink.kafka.shaded.org.apache.kafka.common.security.scram.ScramLoginModule required username="username" password="password";'
)

Utilice la función Artifacts de la consola de Realtime Compute for Apache Flink para cargar el certificado de CA y la clave privada mencionados en el ejemplo. Los archivos cargados se almacenan en el directorio /flink/usrlib. Para usar un archivo de certificado de CA llamado my-truststore.jks, establezca la propiedad 'properties.ssl.truststore.location' en la cláusula WITH de una de las siguientes dos maneras:

  • Establezca 'properties.ssl.truststore.location' = '/flink/usrlib/my-truststore.jks'. Este método evita descargar archivos dinámicamente desde Object Storage Service (OSS) durante la ejecución, pero no es compatible con Debug Mode.

  • Si la versión del motor de Realtime Compute es VVR 11.5 o posterior, configure properties.ssl.truststore.location y properties.ssl.keystore.location con una ruta absoluta de OSS. El formato de la ruta del archivo es oss://flink-fullymanaged-<Workspace ID>/artifacts/namespaces/<Namespace name>/<file name>. Este método descarga dinámicamente los archivos de OSS durante la ejecución de Flink y es compatible con Debug Mode.

Nota
  • Compruebe su configuración: Los ejemplos de este tema muestran configuraciones comunes. Antes de configurar el conector de Kafka, comuníquese con su equipo de operación y mantenimiento de Kafka para obtener los ajustes correctos de seguridad y autenticación.

  • Escape de caracteres: A diferencia de Apache Flink nativo, el editor SQL de Realtime Compute for Apache Flink escapa las comillas dobles (") de forma predeterminada. Por lo tanto, no necesita agregar barras invertidas (\) para escapar las comillas dobles utilizadas en el nombre de usuario y la contraseña dentro de la opción properties.sasl.jaas.config.

Desplazamiento de inicio de la tabla de origen

Modo de arranque

Configure la opción scan.startup.mode para especificar el desplazamiento desde el cual la tabla de origen de Kafka comienza a leer datos. Los valores válidos incluyen:

  • earliest-offset: Comienza a leer desde el desplazamiento más antiguo.

  • latest-offset: Comienza a leer desde el desplazamiento más reciente.

  • group-offsets: Comienza a leer desde los desplazamientos confirmados del grupo de consumidores especificado en properties.group.id.

  • timestamp: Comienza a leer desde el primer mensaje cuya marca de tiempo sea mayor o igual al valor especificado en scan.startup.timestamp-millis.

  • specific-offsets: Comienza a leer desde los desplazamientos de partición específicos indicados en scan.startup.specific-offsets.

Nota
  • Si no especifica un modo de arranque, el valor predeterminado es 'group-offsets'.

  • La opción scan.startup.mode solo aplica a trabajos sin estado. Cuando un trabajo con estado inicia, siempre consume desde los desplazamientos almacenados en su estado.

Ejemplo:

CREATE TEMPORARY TABLE kafka_source (
  ...
) WITH (
  'connector' = 'kafka',
  ...
  -- Consume from the earliest offset.
  'scan.startup.mode' = 'earliest-offset',
  -- Consume from the latest offset.
  'scan.startup.mode' = 'latest-offset',
  -- Consume from the committed offsets of the consumer group "my-group".
  'properties.group.id' = 'my-group',
  'scan.startup.mode' = 'group-offsets',
  'properties.auto.offset.reset' = 'earliest', -- If "my-group" is used for the first time, consumption starts from the earliest offset.
  'properties.auto.offset.reset' = 'latest', -- If "my-group" is used for the first time, consumption starts from the latest offset.
  -- Consume from the specified timestamp in milliseconds: 1655395200000.
  'scan.startup.mode' = 'timestamp',
  'scan.startup.timestamp-millis' = '1655395200000',
  -- Consume from specific offsets.
  'scan.startup.mode' = 'specific-offsets',
  'scan.startup.specific-offsets' = 'partition:0,offset:42;partition:1,offset:300'
);

Prioridad del desplazamiento de inicio

El desplazamiento de inicio de la tabla de origen se determina mediante las siguientes reglas, en orden de prioridad:

Prioridad (de mayor a menor)

El desplazamiento almacenado en un checkpoint o savepoint.

La hora de inicio seleccionada en la consola de Realtime Compute for Apache Flink durante el arranque del trabajo.

El desplazamiento de inicio especificado por scan.startup.mode en la cláusula WITH.

Si no se especifica scan.startup.mode, se utiliza group-offsets para comenzar el consumo desde los desplazamientos del grupo de consumidores correspondiente.

Si el desplazamiento determinado por cualquiera de estos pasos no es válido —por ejemplo, porque expiró o ocurrió un problema en el clúster de Kafka—, el sistema restablece el desplazamiento según la política especificada en properties.auto.offset.reset. Si esta opción no está configurada, el sistema genera una excepción que requiere intervención del usuario.

Un escenario común consiste en iniciar el consumo con un nuevo ID de grupo de consumidores. La tabla de origen primero consulta al clúster de Kafka los desplazamientos confirmados de ese grupo. Como el ID del grupo es nuevo, no se encuentran desplazamientos válidos. En consecuencia, el sistema restablece el desplazamiento según la política especificada en properties.auto.offset.reset. Por lo tanto, cuando consuma con un ID de grupo nuevo, debe configurar la opción properties.auto.offset.reset.

Confirmación de desplazamientos de origen

La tabla de origen de Kafka confirma su desplazamiento de consumo en el clúster de Kafka únicamente después de un checkpoint exitoso. Por ello, un intervalo largo entre checkpoints provoca un retraso en el desplazamiento confirmado. La tabla de origen almacena el progreso real de lectura en el estado del checkpoint, el cual utiliza el sistema para la recuperación ante fallos. Los desplazamientos confirmados sirven solo como monitor de progreso y no se utilizan para la recuperación, por lo que los errores de confirmación no afectan la precisión de los datos.

Particionador de sink personalizado

Si la estrategia de particionamiento integrada de Kafka no cumple con sus requisitos, implemente un particionador personalizado mediante la extensión de la clase FlinkKafkaPartitioner. Una vez finalizado el desarrollo, compile su código en un paquete JAR y cárguelo con la función Artifacts de la consola de Realtime Compute. Después de cargar y referenciar el paquete JAR, establezca el parámetro sink.partitioner de la cláusula WITH con el nombre de clase completo de su particionador; por ejemplo, org.mycompany.MyPartitioner.

Kafka, Upsert Kafka y catálogo JSON de Kafka

Kafka es una plataforma de streaming de eventos de solo anexión que no admite actualizaciones ni eliminaciones de datos. En SQL de streaming, una tabla sink estándar de Kafka no procesa datos de Change Data Capture (CDC) provenientes del flujo superior ni la lógica de retracción de operadores como aggregate y join. Si necesita escribir datos que contengan cambios o retracciones, utilice una tabla sink Upsert Kafka.

Para simplificar la sincronización por lotes de datos de Change Data Capture (CDC) desde una o más tablas de base de datos superiores hacia Kafka, utilice un catálogo JSON de Kafka. Cuando los datos almacenados en Kafka tienen formato JSON, este catálogo le permite omitir la definición del esquema y de los parámetros WITH. Para obtener más detalles, consulte Manage Kafka JSON catalogs.

Ejemplos

Ejemplo 1: Lectura y escritura en Kafka

Este ejemplo lee datos de un topic source de Kafka y los escribe en un topic sink. Los datos tienen formato CSV.

CREATE TEMPORARY TABLE kafka_source (
  id INT,
  name STRING,
  age INT
) WITH (
  'connector' = 'kafka',
  'topic' = 'source',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'properties.group.id' = '<yourKafkaConsumerGroupId>',
  'format' = 'csv'
);

CREATE TEMPORARY TABLE kafka_sink (
  id INT,
  name STRING,
  age INT
) WITH (
  'connector' = 'kafka',
  'topic' = 'sink',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'properties.group.id' = '<yourKafkaConsumerGroupId>',
  'format' = 'csv'
);

INSERT INTO kafka_sink SELECT id, name, age FROM kafka_source;

Ejemplo 2: Sincronización del esquema y los datos de una tabla

El conector de Kafka permite sincronizar mensajes de un topic de Kafka hacia Hologres en tiempo real. Para evitar mensajes duplicados en Hologres durante un failover, utilice el offset y el identificador de partición de los mensajes de Kafka como clave primaria compuesta.

CREATE TEMPORARY TABLE kafkaTable (
  `offset` INT NOT NULL METADATA,
  `part` BIGINT NOT NULL METADATA FROM 'partition',
  PRIMARY KEY (`part`, `offset`) NOT ENFORCED
) WITH (
  'connector' = 'kafka',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'topic' = 'kafka_evolution_demo',
  'scan.startup.mode' = 'earliest-offset',
  'format' = 'json',
  'json.infer-schema.flatten-nested-columns.enable' = 'true'
    -- Optional. Flattens all nested columns.
);

CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka`
WITH (
  'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable;

Ejemplo 3: Sincronización de claves y valores de Kafka

Si la clave de un mensaje de Kafka contiene información relevante, sincronice tanto la clave como el valor.

CREATE TEMPORARY TABLE kafkaTable (
  `key_id` INT NOT NULL,
  `val_name` VARCHAR(200)
) WITH (
  'connector' = 'kafka',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'topic' = 'kafka_evolution_demo',
  'scan.startup.mode' = 'earliest-offset',
  'key.format' = 'json',
  'value.format' = 'json',
  'key.fields' = 'key_id',
  'key.fields-prefix' = 'key_',
  'value.fields-prefix' = 'val_',
  'value.fields-include' = 'EXCEPT_KEY'
);

CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka`(
WITH (
  'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable;
Nota

Las claves de los mensajes de Kafka no admiten Schema Evolution ni el análisis sintáctico automático de tipos. Debe declarar el esquema manualmente.

Ejemplo 4: Sincronización de datos y ejecución de cálculos

Al sincronizar datos de Kafka hacia Hologres, es posible que requiera transformaciones ligeras.

CREATE TEMPORARY TABLE kafkaTable (
  `distinct_id` INT NOT NULL,
  `properties` STRING,
  `timestamp` TIMESTAMP_LTZ METADATA,
  `date` AS CAST(`timestamp` AS DATE)
) WITH (
  'connector' = 'kafka',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'topic' = 'kafka_evolution_demo',
  'scan.startup.mode' = 'earliest-offset',
  'key.format' = 'json',
  'value.format' = 'json',
  'key.fields' = 'key_id',
  'key.fields-prefix' = 'key_'
);

CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka` WITH (
   'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable
ADD COLUMN
  `order_id` AS COALESCE(JSON_VALUE(`properties`, '$.order_id'), 'default');
--Use COALESCE to handle null values.

Ejemplo 5: Análisis sintáctico de JSON anidado

A continuación se muestra un mensaje JSON de ejemplo:

{
  "id": 101,
  "name": "VVP",
  "properties": {
    "owner": "Alibaba Cloud",
    "engine": "Flink"
  }
}

Para evitar el uso de funciones como JSON_VALUE(payload, '$.properties.owner') al analizar campos, defina la estructura directamente en el DDL de origen:

CREATE TEMPORARY TABLE kafka_source (
  id          VARCHAR,
  `name`      VARCHAR,
  properties  ROW<`owner` STRING, engine STRING>
) WITH (
  'connector' = 'kafka',
  'topic' = 'xxx',
  'properties.bootstrap.servers' = 'xxx',
  'scan.startup.mode' = 'earliest-offset',
  'format' = 'json'
);

Con este enfoque, Flink analiza el JSON y lo convierte en campos estructurados durante la fase de lectura. Las consultas SQL posteriores hacen referencia directa a properties.owner sin llamadas adicionales a funciones, lo cual mejora el rendimiento general.

Semántica exactly-once

  • Configuración del nivel de aislamiento del consumidor

    Todas las aplicaciones que consumen datos de Kafka deben establecer la propiedad isolation.level:

    • read_committed: Lee únicamente los datos confirmados.

    • read_uncommitted (predeterminado): Permite leer datos no confirmados.

    El modo EXACTLY_ONCE depende de read_committed. De lo contrario, los consumidores podrían ver datos no confirmados y romper la consistencia.

  • Tiempo de espera de transacción y pérdida de datos

    Durante la recuperación desde un checkpoint, Realtime Compute for Apache Flink considera solo las transacciones confirmadas antes de que dicho checkpoint comenzara. Si el tiempo transcurrido entre la falla de un trabajo y su reinicio supera el tiempo de espera de transacción de Kafka, este cancela automáticamente la transacción abierta, lo que puede provocar pérdida de datos.

    • El valor predeterminado de transaction.max.timeout.ms para un broker de Kafka es de 15 minutos.

    • De forma predeterminada, Flink Kafka Sink establece el parámetro transaction.timeout.ms en 1 hora.

    • Debe aumentar transaction.max.timeout.ms en el broker para que sea mayor o igual que el valor configurado en Flink.

  • Pool de productores y checkpoints simultáneos

    El modo EXACTLY_ONCE utiliza un pool de productores de Kafka de tamaño fijo. Cada checkpoint consume un productor de este pool. Si la cantidad de checkpoints simultáneos supera el tamaño del pool, el trabajo falla.

    Configure el tamaño del pool de productores según el número máximo de checkpoints simultáneos.

  • Restricciones para reducir el paralelismo

    Si un trabajo falla antes de completar el primer checkpoint, la información original del pool de productores se pierde al reiniciar. Por lo tanto, no reduzca el paralelismo del trabajo antes de que finalice el primer checkpoint. Si la reducción es necesaria, el nuevo paralelismo no debe ser menor que FlinkKafkaProducer.SAFE_SCALE_DOWN_FACTOR.

  • Las transacciones bloquean las lecturas

    En el modo read_committed, cualquier transacción que no se haya confirmado ni cancelado bloquea las operaciones de lectura en todo el topic.

    Por ejemplo:

    • La transacción 1 escribe datos.

    • La transacción 2 escribe más datos y se confirma.

    • Mientras la transacción 1 permanezca abierta, los datos de la transacción 2 confirmada resultan invisibles para los consumidores.

    Esto tiene las siguientes implicaciones:

    • Durante la operación normal, la latencia de visibilidad de los datos equivale aproximadamente al intervalo del checkpoint.

    • Si un trabajo falla, cualquier topic donde escribía queda bloqueado para los consumidores hasta que el trabajo se reinicie o la transacción agote su tiempo de espera. En casos extremos, el propio proceso de tiempo de espera de la transacción también afecta las operaciones de lectura.

Preguntas frecuentes