Todos los productos
Search
Centro de documentos

Realtime Compute for Apache Flink:MaxCompute connector

Última actualización: Sep 25, 2026

El conector de MaxCompute permite leer y escribir datos en MaxCompute (anteriormente ODPS), la plataforma de almacenamiento de datos a escala de exabytes totalmente gestionada de Alibaba Cloud, directamente desde trabajos de Flink SQL y DataStream.

Capacidades

Elemento

Descripción

Tipos de tabla

Tabla de origen, tabla de dimensiones, tabla de destino y destino de ingesta de datos

Modos de ejecución

Modo streaming y modo por lotes

Tipos de API

DataStream API, SQL API y trabajos YAML de ingesta de datos

Semántica

At-least-once

Actualización o eliminación de datos en una tabla de destino

Batch Tunnel o Streaming Tunnel: solo inserción. Upsert Tunnel: inserción, actualización y eliminación.

Métricas

Tipo de tabla

Métricas

Origen

numRecordsIn, numRecordsInPerSecond, numBytesIn, numBytesInPerSecond

Destino

numRecordsOut, numRecordsOutPerSecond, numBytesOut, numBytesOutPerSecond

Tabla de dimensiones

dim.odps.cacheSize

Para obtener más información, consulte Métricas de monitoreo .

Requisitos previos

Antes de empezar, asegúrese de contar con lo siguiente:

Límites

  • El conector admite únicamente la semántica at-least-once. Pueden aparecer registros duplicados en MaxCompute según el tunnel que utilice. Para obtener orientación sobre cómo elegir un tunnel, consulte la sección "How do I select a data tunnel?" de FAQ about upstream and downstream storage.

  • De forma predeterminada, un origen opera en modo completo: lee únicamente la partición especificada mediante la opción partition. Una vez leídos todos los datos, el trabajo finaliza y no monitorea nuevas particiones. Para monitorear continuamente las nuevas particiones, configure un origen incremental con startPartition.

  • Cada vez que se actualiza la caché de una tabla de dimensiones, esta comprueba si existe una partición más reciente. Después de iniciar, el origen no lee los datos nuevos que se agreguen a una partición que ya esté leyendo; ejecute un despliegue solo cuando la partición contenga los datos completos.

Elección de un tunnel

MaxCompute ofrece tres tunnels para escribir datos desde Flink. Elija uno según su caso de uso:

Tunnel

Predeterminado

Cuándo usarlo

MaxCompute Batch Tunnel

Sí (useStreamTunnel=false, enableUpsert=false)

Cargas por lotes; los datos están disponibles solo después de generar un checkpoint. Establezca flushIntervalMs=0 para deshabilitar el vaciado programado.

MaxCompute Streaming Tunnel

No (useStreamTunnel=true)

Ingesta casi en tiempo real; los datos vaciados están disponibles de inmediato en MaxCompute.

MaxCompute Upsert Tunnel

No (enableUpsert=true)

Operaciones INSERT, UPDATE y DELETE en una tabla Delta de MaxCompute. Requiere VVR 8.0.6 o superior.

Para ver una comparación detallada, consulte la sección "How do I select a data tunnel?" de FAQ about upstream and downstream storage.

SQL

El conector de MaxCompute se utiliza como tabla de origen, de dimensiones o de destino en trabajos basados en SQL.

Sintaxis

CREATE TEMPORARY TABLE odps_source(
  id INT,
  user_name VARCHAR,
  content VARCHAR
) WITH (
  'connector' = 'odps',
  'endpoint' = '<yourEndpoint>',
  'project' = '<yourProjectName>',
  'schemaName' = '<yourSchemaName>',
  'tableName' = '<yourTableName>',
  'accessId' = '${secret_values.ak_id}',
  'accessKey' = '${secret_values.ak_secret}',
  'partition' = 'ds=2018****'
);

Opciones del conector

Opciones generales

Opción Obligatorio Predeterminado Tipo Descripción
connector Sí — STRING Establézcalo en odps.
endpoint Sí — STRING Endpoint de MaxCompute. Consulte Endpoint.
tunnelEndpoint No — STRING Endpoint de MaxCompute Tunnel. Si no se especifica, MaxCompute asigna las conexiones del tunnel mediante Server Load Balancer (SLB).
project Sí — STRING Nombre del proyecto de MaxCompute.
schemaName No — STRING Obligatorio solo cuando la función de esquema de MaxCompute está habilitada. Establézcalo con el nombre del esquema de la tabla. Consulte Operaciones de esquema. VVR 8.0.6 o superior.
tableName Sí — STRING Nombre de la tabla de MaxCompute.
accessId Sí — STRING AccessKey ID utilizado para acceder a MaxCompute. Consulte How do I view my AccessKey ID and AccessKey secret?
Importante

Almacene el AccessKey ID como variable. Consulte Manage variables.

accessKey Sí — STRING AccessKey secret utilizado para acceder a MaxCompute.
partition No — STRING Nombre de la partición en la tabla de MaxCompute. No es obligatorio para tablas sin particiones ni para orígenes incrementales. Consulte la sección "How do I configure the partition option?" de FAQ about upstream and downstream storage.
compressAlgorithm No SNAPPY STRING Algoritmo de compresión para MaxCompute Tunnel. Valores válidos: RAW (sin compresión), ZLIB, SNAPPY. En escenarios de prueba, SNAPPY mejora el rendimiento aproximadamente un 50 % en comparación con ZLIB.
quotaName No — STRING Nombre de la cuota para resource groups exclusivos de MaxCompute Tunnel. VVR 8.0.3 o superior. Este parámetro surte efecto solo cuando endpoint se establece en una dirección VPC. Si se usa un endpoint público o se especifica tunnelEndpoint, este parámetro no surte efecto.

Opciones de origen

Opción

Obligatorio

Predeterminado

Tipo

Descripción

maxPartitionCount

No

100

INTEGER

Número máximo de particiones desde las cuales leer. Si se supera, aparece el error "The number of matched partitions exceeds the default limit". Leer demasiadas particiones puede sobrecargar MaxCompute y ralentizar el inicio del trabajo; aumente este valor solo cuando su carga de trabajo lo requiera.

useArrow

No

false

BOOLEAN

Lee datos con el formato Arrow, que llama a la API de almacenamiento de MaxCompute. Solo para despliegues por lotes. VVR 8.0.8 o superior.

splitSize

No

256 MB

MEMORYSIZE

Cantidad de datos extraídos por división al usar el formato Arrow. Solo para despliegues por lotes. VVR 8.0.8 o superior.

compressCodec

No

"" (ninguno)

STRING

Algoritmo de compresión para lecturas con el formato Arrow. Valores válidos: "" (ninguno), ZSTD, LZ4_FRAME. Especificar un códec mejora el rendimiento frente a la ausencia de compresión. Solo para despliegues por lotes. VVR 8.0.8 o superior.

dynamicLoadBalance

No

false

BOOLEAN

Habilita la asignación dinámica de fragmentos para mejorar el rendimiento de procesamiento y reducir el tiempo total de lectura. Tenga en cuenta que esto puede provocar sesgo de datos, ya que distintos operadores leen cantidades inconsistentes. Solo para despliegues por lotes. VVR 8.0.8 o superior.

Opciones de origen incremental

El origen incremental consulta MaxCompute de forma intermitente para detectar nuevas particiones. Antes de leer una partición nueva, deben haber concluido todas las escrituras de datos en ella. Para más detalles, consulte la sección "What do I do if an incremental source detects a new partition while data is still being written?" de FAQ about upstream and downstream storage.

Orden de las particiones: El origen lee las particiones cuyo orden alfabético sea mayor o igual que el valor de startPartition. Por ejemplo, year=2023,month=10 se ordena antes que year=2023,month=9 alfabéticamente. Por ello, rellene los valores de mes con ceros (use year=2023,month=09 en lugar de year=2023,month=9) para garantizar un orden correcto.

Opción

Obligatorio

Predeterminado

Tipo

Descripción

startPartition

Sí

—

STRING

Partición inicial para lecturas incrementales. Cuando se especifica, se ignora partition. En tablas con varios niveles de partición, configure los valores de las columnas de partición en orden descendente por nivel. Consulte la sección "How do I configure startPartition?" de FAQ about upstream and downstream storage.

subscribeIntervalInSec

No

30

INTEGER

Intervalo de sondeo en segundos.

modifiedTableOperation

No

NONE

Enum

Acción que se ejecuta cuando una partición se modifica durante la lectura. Las sesiones de descarga se guardan en los checkpoints; si los datos de una partición cambian después de iniciar una sesión, la reanudación desde el checkpoint falla y el despliegue se reinicia repetidamente. Valores válidos: NONE: actualiza startPartition para omitir la partición no disponible y reiniciar sin estado; SKIP: omite automáticamente la partición no disponible al reanudar. VVR 8.0.3 o superior. Con cualquiera de estos valores, se conservan los datos ya leídos de la partición modificada y se descartan los no leídos.

Opciones de destino

Opción

Obligatorio

Predeterminado

Tipo

Descripción

useStreamTunnel

No

false

BOOLEAN

Usa MaxCompute Streaming Tunnel en lugar de Batch Tunnel. true: Streaming Tunnel; false: Batch Tunnel. Consulte Elección de un tunnel.

flushIntervalMs

No

30000 (30 s)

LONG

Intervalo de vaciado del búfer del escritor del tunnel, en milisegundos. Para Streaming Tunnel: los datos vaciados están disponibles de inmediato. Para Batch Tunnel: los datos están disponibles solo después de generar un checkpoint; establézcalo en 0 para deshabilitar el vaciado programado. Se activa cuando se alcanza flushIntervalMs o batchSize.

batchSize

No

67108864 (64 MB)

LONG

Tamaño del búfer en bytes. Los datos se vacían cuando el búfer alcanza este tamaño. Se activa cuando se alcanza batchSize o flushIntervalMs.

numFlushThreads

No

1

INTEGER

Número de hilos utilizados para vaciar el búfer del escritor del tunnel. Los valores mayores que 1 permiten vaciar varias particiones de forma concurrente.

slotNum

No

0

INTEGER

Número de slots de Tunnel para recibir datos de Flink. Consulte Descripción general del servicio de transmisión de datos para conocer los límites de slots.

dynamicPartitionLimit

No

100

INTEGER

Número máximo de particiones dinámicas escritas entre dos checkpoints. Si se supera, aparece el error "Too many dynamic partitions". Escribir en muchas particiones aumenta la carga en MaxCompute y ralentiza la generación de checkpoints; aumente este valor solo cuando su carga de trabajo lo requiera.

retryTimes

No

3

INTEGER

Número máximo de reintentos para solicitudes al servidor de MaxCompute (creación de sesiones, envíos o fallos de vaciado).

sleepMillis

No

1000

INTEGER

Intervalo entre reintentos, en milisegundos.

enableUpsert

No

false

BOOLEAN

Usa MaxCompute Upsert Tunnel. true: procesa registros INSERT, UPDATE_AFTER y DELETE; false: usa el tunnel especificado por useStreamTunnel. VVR 8.0.6 o superior. Si el destino presenta errores o fallas prolongadas durante las confirmaciones de sesión en modo upsert, establezca el paralelismo del operador de destino en 10 o menos.

upsertAsyncCommit

No

false

BOOLEAN

Usa el modo asíncrono al confirmar sesiones upsert. Este modo reduce el tiempo de confirmación, pero los datos confirmados no se pueden consultar de inmediato. VVR 8.0.6 o superior.

upsertCommitTimeoutMs

No

120000 (120 s)

INTEGER

Tiempo de espera para confirmaciones de sesiones upsert, en milisegundos. VVR 8.0.6 o superior.

sink.operation

No

insert

STRING

Modo de escritura para una tabla Delta. insert: modo de anexión; upsert: modo de actualización. VVR 8.0.10 o superior.

sink.parallelism

No

—

INTEGER

Paralelismo de escritura para una tabla Delta. De forma predeterminada, toma el paralelismo del flujo ascendente. El valor de write.bucket.num debe ser múltiplo entero de sink.parallelism para lograr un rendimiento de escritura óptimo y eficiencia de memoria. VVR 8.0.10 o superior.

sink.file-cached.enable

No

false

BOOLEAN

Habilita el modo de caché de archivos al escribir en particiones dinámicas de una tabla Delta. Reduce la cantidad de archivos pequeños escritos en el servidor, pero aumenta la latencia de escritura. Habilítelo cuando el destino tenga un paralelismo alto. VVR 8.0.10 o superior.

sink.file-cached.writer.num

No

16

INTEGER

Hilos de carga concurrentes por tarea en el modo de caché de archivos. Evite establecer un valor demasiado alto, ya que escribir en muchas particiones simultáneamente puede provocar errores de falta de memoria (OOM). Solo tiene efecto cuando sink.file-cached.enable=true. VVR 8.0.10+.

sink.bucket.check-interval

No

60000

INTEGER

Intervalo de comprobación del tamaño de archivo en el modo de caché de archivos, en milisegundos. Solo tiene efecto cuando sink.file-cached.enable=true. VVR 8.0.10+.

sink.file-cached.rolling.max-size

No

16 MB

MEMORYSIZE

Tamaño máximo de un solo archivo en caché. Al superarse, los datos se cargan en el servidor. Solo tiene efecto cuando sink.file-cached.enable=true. VVR 8.0.10+.

sink.file-cached.memory

No

64 MB

MEMORYSIZE

Memoria máxima fuera del heap para escrituras de archivos en el modo de caché de archivos. Solo tiene efecto cuando sink.file-cached.enable=true. VVR 8.0.10+.

sink.file-cached.memory.segment-size

No

128 KB

MEMORYSIZE

Tamaño del segmento de búfer para escrituras de archivos en el modo de caché de archivos. Solo tiene efecto cuando sink.file-cached.enable=true. VVR 8.0.10+.

sink.file-cached.flush.always

No

true

BOOLEAN

Indica si se usa la caché al escribir archivos en el modo de caché de archivos. Solo tiene efecto cuando sink.file-cached.enable=true. VVR 8.0.10+.

sink.file-cached.write.max-retries

No

3

INTEGER

Número de reintentos para cargas de datos en el modo de caché de archivos. Solo tiene efecto cuando sink.file-cached.enable=true. VVR 8.0.10+.

upsert.writer.max-retries

No

3

INTEGER

Número máximo de reintentos para escribir en un bucket dentro de una sesión de Upsert Writer. VVR 8.0.10 o superior.

upsert.writer.buffer-size

No

64 MB

MEMORYSIZE

Tamaño total del búfer en todos los buckets de una sesión de Upsert Writer. Los datos se vacían cuando el total alcanza este umbral. Auméntelo para mejorar la eficiencia de escritura; redúzcalo si escribir en muchas particiones provoca errores OOM. VVR 8.0.10 o superior.

upsert.writer.bucket.buffer-size

No

1 MB

MEMORYSIZE

Tamaño del búfer por bucket en una sesión de Upsert Writer. Redúzcalo si la memoria del servidor de Flink es insuficiente. VVR 8.0.10 o superior.

upsert.write.bucket.num

Sí

—

INTEGER

Número de buckets para la tabla Delta de destino. Debe coincidir con el valor de write.bucket.num configurado en la tabla Delta. VVR 8.0.10 o superior.

upsert.write.slot-num

No

1

INTEGER

Slots de Tunnel por sesión upsert. VVR 8.0.10 o superior.

upsert.commit.max-retries

No

3

INTEGER

Número máximo de reintentos para confirmaciones de sesiones upsert. VVR 8.0.10 o superior.

upsert.commit.thread-num

No

16

INTEGER

Paralelismo para confirmaciones de sesiones upsert. Evite valores grandes, ya que un exceso de confirmaciones concurrentes aumenta el consumo de recursos y puede causar problemas de rendimiento. VVR 8.0.10 o superior.

upsert.commit.timeout

No

600

INTEGER

Tiempo de espera para confirmaciones de sesiones upsert, en segundos. VVR 8.0.10 o superior.

upsert.flush.concurrent

No

2

INTEGER

Número máximo de vaciados de buckets concurrentes por partición. Cada vaciado ocupa un slot de Tunnel. VVR 8.0.10 o superior.

insert.commit.thread-num

No

16

INTEGER

Paralelismo para confirmaciones de sesiones de inserción. VVR 8.0.10 o superior.

insert.arrow-writer.enable

No

false

BOOLEAN

Usa el formato Arrow para inserciones. VVR 8.0.10 o superior.

insert.arrow-writer.batch-size

No

512

INTEGER

Número máximo de filas por lote en formato Arrow. VVR 8.0.10 o superior.

insert.arrow-writer.flush-interval

No

100000

INTEGER

Intervalo de vaciado del escritor, en milisegundos. VVR 8.0.10 o superior.

insert.writer.buffer-size

No

64 MB

MEMORYSIZE

Tamaño de la caché para el escritor con búfer. VVR 8.0.10 o superior.

upsert.partial-column.enable

No

false

BOOLEAN

Actualiza únicamente las columnas especificadas (actualización parcial de columnas). Aplica solo a destinos de tabla Delta. Consulte Actualizar datos en columnas específicas. Cuando es true: si existe un registro con la misma clave primaria, se sobrescriben los campos no nulos especificados; si no hay coincidencias, se inserta un nuevo registro con los valores indicados para las columnas especificadas y null para el resto. VVR 8.0.11 o superior.

Opciones de tabla de dimensiones

Cuando se inicia un despliegue, la tabla de dimensiones carga todos los datos de la partición especificada por partition. La opción partition es compatible con la función max_pt(). Al recargar la caché, se vuelve a leer la partición más reciente. Establezca partition en max_two_pt() para cargar datos de dos particiones.

Las tablas de dimensiones requieren cache=ALL . Aumente la memoria del nodo de unión a como mínimo cuatro veces el tamaño de los datos de la tabla remota. Para tablas de dimensiones grandes, use la sugerencia SHUFFLE_HASH para distribuir los datos de manera uniforme. En tablas extremadamente grandes que provoquen recolecciones de basura (GC) frecuentes en la máquina virtual Java (JVM), conviértalas a una tabla de dimensiones de clave-valor con una política de caché LRU (Least Recently Used); por ejemplo, una tabla de dimensiones de ApsaraDB for HBase.

Opción

Obligatorio

Predeterminado

Tipo

Descripción

cache

Sí

—

STRING

Política de caché. Debe establecerse en ALL y declararse explícitamente en la instrucción DDL. Todos los datos de la tabla de dimensiones se cargan en la caché antes de ejecutar el despliegue. Las búsquedas posteriores consultan únicamente la caché, la cual se recarga cuando caducan sus entradas.

cacheSize

No

100000

LONG

Número máximo de filas que se almacenan en caché. Si se supera, aparece el error "Row count of table <table-name> partition <partition-name> exceeds maxRowCount limit". Las cachés grandes consumen mucha memoria heap de la JVM y ralentizan el inicio y la actualización; aumente este valor solo cuando su carga de trabajo lo requiera.

cacheTTLMs

No

Long.MAX_VALUE

LONG

Tiempo de espera de la caché, en milisegundos.

cacheReloadTimeBlackList

No

—

STRING

Periodos durante los cuales no se actualiza la caché. Úselo en horas de tráfico pico (como eventos promocionales) para evitar inestabilidad en el despliegue por las actualizaciones. Consulte la sección "How do I configure cacheReloadTimeBlackList?" de FAQ about upstream and downstream storage.

maxLoadRetries

No

10

INTEGER

Número máximo de reintentos para la carga inicial de la caché al iniciar el despliegue. Si se agotan los reintentos, el despliegue falla.

Asignaciones de tipos de datos

Para consultar la lista completa de tipos de datos de MaxCompute, visite Sistema de tipos de datos de MaxCompute versión 2.0.

Tipo de MaxCompute

Tipo de Flink

BOOLEAN

BOOLEAN

TINYINT

TINYINT

SMALLINT

SMALLINT

INT

INTEGER

BIGINT

BIGINT

FLOAT

FLOAT

DOUBLE

DOUBLE

DECIMAL(precision, scale)

DECIMAL(precision, scale)

CHAR(n)

CHAR(n)

VARCHAR(n)

VARCHAR(n)

STRING

STRING

BINARY

BYTES

DATE

DATE

DATETIME

TIMESTAMP(3)

TIMESTAMP

TIMESTAMP(9)

TIMESTAMP_NTZ

TIMESTAMP(9)

ARRAY

ARRAY

MAP

MAP

STRUCT

ROW

JSON

STRING

VECTOR

VECTOR

Importante

Si una tabla física de MaxCompute contiene campos de tipo compuesto anidado (ARRAY, MAP o STRUCT) o un campo JSON, establezca tblproperties('columnar.nested.type'='true') al crear la tabla. Esto permite que Realtime Compute for Apache Flink lea y escriba los datos correctamente.

Flink CDC (vista previa pública)

El conector de MaxCompute ingesta datos de Change Data Capture (CDC) como destino en trabajos basados en YAML. Requiere VVR 11.1 o superior.

Sintaxis

source:
  type: xxx

sink:
  type: maxcompute
  name: MaxComputeSink
  access-id: ${your_accessId}
  access-key: ${your_accessKey}
  endpoint: ${your_maxcompute_endpoint}
  project: ${your_project}
  buckets-num: 8

Opciones de configuración

Opción

Obligatorio

Predeterminado

Tipo

Descripción

type

Sí

—

String

Establézcalo en maxcompute.

name

No

—

String

Nombre del destino.

access-id

Sí

—

String

AccessKey ID de su cuenta de Alibaba Cloud o usuario RAM. Obténgalo en la consola de Resource Access Management (RAM).

access-key

Sí

—

String

AccessKey secret.

endpoint

Sí

—

String

Endpoint de MaxCompute. Configúrelo según la región y el método de conexión de red. Consulte Endpoint.

project

Sí

—

String

Nombre del proyecto de MaxCompute. Para encontrarlo, inicie sesión en MaxCompute console, vaya a Workspace > Projects y copie el nombre del proyecto.

tunnel.endpoint

No

—

String

Endpoint de MaxCompute Tunnel. Normalmente se infiere de forma automática. Es obligatorio en entornos de red especiales, como al usar un servidor proxy.

quota.name

No

—

String

Nombre de la cuota para un exclusive resource group. Si no se especifica, se utiliza un resource group compartido. Este parámetro surte efecto solo cuando endpoint se establece en una dirección VPC. Si se usa un endpoint público o se especifica tunnel.endpoint, este parámetro no surte efecto.

sts-token

No

—

String

Token de Security Token Service (STS) para la autenticación de roles RAM. Obligatorio al acceder a MaxCompute con un rol RAM.

buckets-num

No

16

Integer

Número de buckets para una tabla Delta de MaxCompute creada automáticamente. Consulte Almacén de datos casi en tiempo real.

compress.algorithm

No

zlib

String

Algoritmo de compresión de datos. Valores válidos: raw (sin compresión), zlib, snappy.

total.buffer-size

No

64 MB

String

Tamaño del búfer en memoria. Para tablas particionadas: aplica por partición. Para tablas sin particiones: aplica por tabla. Los búferes de distintas particiones o tablas son independientes. Los datos se vacían cuando el búfer se llena.

bucket.buffer-size

No

4 MB

String

Tamaño del búfer por bucket. Aplica únicamente al escribir en tablas Delta de MaxCompute.

commit.thread-num

No

16

Integer

Número máximo de particiones o tablas confirmadas de forma concurrente durante la generación de checkpoints.

flush.concurrent-num

No

4

Integer

Número máximo de buckets vaciados de forma concurrente. Aplica únicamente al escribir en tablas Delta de MaxCompute.

Asignaciones de ubicaciones de tablas

Cuando el conector crea tablas automáticamente en MaxCompute, las ubicaciones se asignan de la siguiente manera:

Importante

Si la función de esquema está deshabilitada en su proyecto de MaxCompute, el conector ignora tableId.namespace. En este caso, solo se ingesta una única base de datos (o su equivalente lógico) en MaxCompute; por ejemplo, solo una base de datos MySQL al ingerir desde MySQL.

Ubicación en MySQL

Abstracción de Flink CDC

Ubicación en MaxCompute

N/D

Proyecto (desde la configuración)

Proyecto

Base de datos

TableId.namespace

Esquema (ignorado si el esquema está deshabilitado)

Tabla

TableId.tableName

Tabla

Asignaciones de tipos de datos

Tipo de Flink CDC

Tipo de MaxCompute

CHAR

STRING

VARCHAR

STRING

BOOLEAN

BOOLEAN

BINARY/VARBINARY

BINARY

DECIMAL

DECIMAL

TINYINT

TINYINT

SMALLINT

SMALLINT

INTEGER

INTEGER

BIGINT

BIGINT

FLOAT

FLOAT

DOUBLE

DOUBLE

TIME_WITHOUT_TIME_ZONE

STRING

DATE

DATE

TIMESTAMP_WITHOUT_TIME_ZONE

TIMESTAMP_NTZ

TIMESTAMP_WITH_LOCAL_TIME_ZONE (precision > 3)

TIMESTAMP

TIMESTAMP_WITH_LOCAL_TIME_ZONE (precision <= 3)

DATETIME

TIMESTAMP_WITH_TIME_ZONE (precision > 3)

TIMESTAMP

TIMESTAMP_WITH_TIME_ZONE (precision <= 3)

DATETIME

ARRAY

ARRAY

MAP

MAP

ROW

STRUCT

Cambios de esquema

Un trabajo de canalización YAML de CDC admite varias estrategias para cambios de esquema. Configure el parámetro de nivel de canalización schema.change.behavior para especificar cómo se sincronizan dichos cambios. Para obtener más información, consulte Schema evolution configurations. Los valores válidos de schema.change.behavior son IGNORE, LENIENT, TRY_EVOLVE, EVOLVE y EXCEPTION. Solo LENIENT y EVOLVE implican cambios de esquema. A continuación se describe cómo se gestionan los eventos de cambio de esquema en ambos modos.

LENIENT (predeterminado)

El modo LENIENT gestiona los siguientes cambios de esquema:

  • Agregar una columna anulable: la columna se agrega al final del esquema de la tabla de destino y sus datos se sincronizan automáticamente.

  • Eliminar una columna anulable: la columna no se elimina de la tabla de destino. Sus datos se rellenan automáticamente con valores NULL.

  • Agregar una columna no anulable: la columna se agrega al final del esquema de la tabla de destino y sus datos se sincronizan automáticamente. De forma predeterminada, la nueva columna es anulable. Los datos generados antes de agregarla se establecen en NULL.

  • Cambiar el nombre de una columna: el evento se trata como la adición de una columna y la eliminación de otra. La columna renombrada se agrega al final de la tabla de destino y los datos de la columna original se rellenan automáticamente con valores NULL. Por ejemplo, si col_a se renombra a col_b, col_b se agrega al final de la tabla de destino y los datos de col_a se rellenan con valores NULL.

  • Cambiar el tipo de datos de una columna: el tipo de datos de la columna se modifica en la tabla de destino.

  • Los siguientes cambios de esquema no son compatibles:

    • Cambiar una columna de NULLABLE a NOT NULL.

EVOLVE

El modo EVOLVE gestiona los siguientes cambios de esquema:

  • Agregar una columna anulable: compatible.

  • Eliminar una columna anulable: no compatible.

  • Agregar una columna no anulable: se agrega una columna anulable a la tabla de destino.

  • Cambiar el nombre de una columna: compatible. La columna original en la tabla de destino se renombra.

  • Cambiar el tipo de datos de una columna: el tipo de datos de la columna se modifica en la tabla de destino.

  • Los siguientes cambios de esquema no son compatibles:

    • Cambiar una columna de NULLABLE a NOT NULL.

Para ver un ejemplo de cómo habilitar el modo EVOLVE, consulte Enable EVOLVE mode.

Nota

Si la tabla de destino de MaxCompute ya existe, el conector escribe los datos según el esquema existente y no vuelve a crearla. Si dicho esquema difiere del de la tabla de origen, se reporta un error de validación de tipos. Si inicia un trabajo desde un estado vacío, elimine previamente la tabla de destino y permita que el trabajo la cree.

Ejemplos de configuración

A continuación se muestran las configuraciones de escenarios típicos.

Escritura en una tabla particionada

El campo create_time de tipo TIMESTAMP en la tabla de origen se convierte al tipo DATE y se utiliza como clave de partición de la tabla de MaxCompute.

source:
    type: mysql
    name: MySQL Source
    hostname: <yourHostname>
    port: 3306
    username: flink
    password: ${secret_values.password}
    tables: test_db.test_source_table
    server-id: 5401-5499
    # (Optional) Synchronize the data of tables created in the incremental phase.
    scan.binlog.newly-added-table.enabled: true
    # (Optional) Synchronize table comments and column comments.
    include-comments.enabled: true
    # (Optional) Assign unbounded chunks first to prevent possible TaskManager out-of-memory errors.
    scan.incremental.snapshot.unbounded-chunk-first.enabled: true
    # (Optional) Enable parse filtering to accelerate reads.
    scan.only.deserialize.captured.tables.changelog.enabled: true

  sink:
    type: maxcompute
    name: MaxComputeSink
    access-id: ${your_accessId}
    access-key: ${your_accessKey}
    endpoint: ${your_maxcompute_endpoint}
    project: ${your_project}
    buckets-num: 8
 
  transform:
    - source-table: test_db.test_source_table
      projection: \*, DATE_FORMAT(CAST(create_time AS TIMESTAMP), 'yyyy-MM-dd') as partition_key
      primary-keys: id, create_time, partition_key
      partition-keys: partition_key
      description: add partition key 

  pipeline:
    name: MySQL to MaxCompute Pipeline

Sincronizar una sola tabla

Sincronice las tablas que requieren un alto rendimiento en tiempo real y estabilidad mediante trabajos de sincronización de tabla única. De esta manera se evitan los riesgos de complejidad que genera la sincronización de varias tablas. A continuación se muestra un ejemplo de configuración:

source:
    type: mysql
    name: MySQL Source
    hostname: <yourHostname>
    port: 3306
    username: flink
    password: ${secret_values.password}
    tables: test_db.test_source_table
    server-id: 5401-5499
    # (Optional) Synchronize table comments and column comments.
    include-comments.enabled: true
    # (Optional) Assign unbounded chunks first to prevent possible TaskManager out-of-memory errors.
    scan.incremental.snapshot.unbounded-chunk-first.enabled: true
    # (Optional) Enable parse filtering to accelerate reads.
    scan.only.deserialize.captured.tables.changelog.enabled: true

  sink:
    type: maxcompute
    name: MaxComputeSink
    access-id: ${your_accessId}
    access-key: ${your_accessKey}
    endpoint: ${your_maxcompute_endpoint}
    project: ${your_project}
    buckets-num: 8

  pipeline:
    name: MySQL to MaxCompute Pipeline

Sincronizar una base de datos completa

La sincronización de bases de datos completas reduce la cantidad de trabajos de sincronización que debe configurar y ejecutar, lo cual disminuye los costos de operación y mantenimiento. A continuación se muestra un ejemplo de configuración:

source:
    type: mysql
    name: MySQL Source
    hostname: <yourHostname>
    port: 3306
    username: flink
    password: ${secret_values.password}
    tables: test_db.\.*
    server-id: 5401-5499
    # (Optional) Synchronize the data of tables created in the incremental phase.
    scan.binlog.newly-added-table.enabled: true
    # (Optional) Synchronize table comments and column comments.
    include-comments.enabled: true
    # (Optional) Assign unbounded chunks first to prevent possible TaskManager out-of-memory errors.
    scan.incremental.snapshot.unbounded-chunk-first.enabled: true
    # (Optional) Enable parse filtering to accelerate reads.
    scan.only.deserialize.captured.tables.changelog.enabled: true

  sink:
    type: maxcompute
    name: MaxComputeSink
    access-id: ${your_accessId}
    access-key: ${your_accessKey}
    endpoint: ${your_maxcompute_endpoint}
    project: ${your_project}
    buckets-num: 8

  pipeline:
    name: MySQL to MaxCompute Pipeline

Sincronizar una base de datos completa y cambiar el nombre de bases de datos y tablas

A partir de la sincronización de bases de datos completas, puede agregar el módulo route para cambiar el nombre de las bases de datos y las tablas de forma uniforme. A continuación se muestra un ejemplo de configuración:

source:
    type: mysql
    name: MySQL Source
    hostname: <yourHostname>
    port: 3306
    username: flink
    password: ${secret_values.password}
    tables: test_db.\.*
    server-id: 5401-5499
    # (Optional) Synchronize the data of tables created in the incremental phase.
    scan.binlog.newly-added-table.enabled: true
    # (Optional) Synchronize table comments and column comments.
    include-comments.enabled: true
    # (Optional) Assign unbounded chunks first to prevent possible TaskManager out-of-memory errors.
    scan.incremental.snapshot.unbounded-chunk-first.enabled: true
    # (Optional) Enable parse filtering to accelerate reads.
    scan.only.deserialize.captured.tables.changelog.enabled: true

  sink:
    type: maxcompute
    name: MaxComputeSink
    access-id: ${your_accessId}
    access-key: ${your_accessKey}
    endpoint: ${your_maxcompute_endpoint}
    project: ${your_project}
    buckets-num: 8
  
  route:
    # Synchronize all tables in the MySQL test_db database to the MaxCompute test_db2 database and retain the table names.
    - source-table: test_db.\.*
      sink-table: test_db2.<>
      replace-symbol: <>

  pipeline:
    name: MySQL to MaxCompute Pipeline

Combinar tablas fragmentadas

Para escribir los datos de varias tablas fragmentadas en una sola tabla de destino, utilice la siguiente plantilla de configuración:

source:
    type: mysql
    name: MySQL Source
    hostname: <yourHostname>
    port: 3306
    username: flink
    password: ${secret_values.password}
    tables: test_db.user\.*
    server-id: 5401-5499
    # (Optional) Synchronize the data of tables created in the incremental phase.
    scan.binlog.newly-added-table.enabled: true
    # (Optional) Synchronize table comments and column comments.
    include-comments.enabled: true
    # (Optional) Assign unbounded chunks first to prevent possible TaskManager out-of-memory errors.
    scan.incremental.snapshot.unbounded-chunk-first.enabled: true
    # (Optional) Enable parse filtering to accelerate reads.
    scan.only.deserialize.captured.tables.changelog.enabled: true

  sink:
    type: maxcompute
    name: MaxComputeSink
    access-id: ${your_accessId}
    access-key: ${your_accessKey}
    endpoint: ${your_maxcompute_endpoint}
    project: ${your_project}
    buckets-num: 8
  
  route:
    # All sharded tables in MySQL test_db are merged into one MaxCompute table named test_db.user.
    - source-table: test_db.user\.*
      sink-table: test_db.user

  pipeline:
    name: MySQL to MaxCompute Pipeline

Sincronizar tablas existentes después de reiniciar

Para agregar tablas existentes a la sincronización, establezca scan.newly-added-table.enabled en true y reinicie el trabajo.

Importante

Si un trabajo tiene establecido scan.binlog.newly-added-table.enabled en true para capturar tablas nuevas, no es posible reiniciarlo con scan.newly-added-table.enabled en true para capturar tablas existentes. De lo contrario, los datos se duplican.

source:
    type: mysql
    name: MySQL Source
    hostname: <yourHostname>
    port: 3306
    username: flink
    password: ${secret_values.password}
    tables: test_db.\.*
    server-id: 5401-5499
    scan.startup.mode: initial
    # When the job restarts, check the new tables captured by the tables parameter and take a snapshot.
    # Note: Use this parameter together with scan.startup.mode: initial.
    scan.newly-added-table.enabled: true
    # (Optional) Synchronize the data of tables created in the incremental phase.
    scan.binlog.newly-added-table.enabled: true
    # (Optional) Synchronize table comments and column comments.
    include-comments.enabled: true
    # (Optional) Assign unbounded chunks first to prevent possible TaskManager out-of-memory errors.
    scan.incremental.snapshot.unbounded-chunk-first.enabled: true
    # (Optional) Enable parse filtering to accelerate reads.
    scan.only.deserialize.captured.tables.changelog.enabled: true

  sink:
    type: maxcompute
    name: MaxComputeSink
    access-id: ${your_accessId}
    access-key: ${your_accessKey}
    endpoint: ${your_maxcompute_endpoint}
    project: ${your_project}
    buckets-num: 8

  pipeline:
    name: MySQL to MaxCompute Pipeline

Excluir tablas específicas durante la sincronización de una base de datos completa

Para excluir tablas específicas durante la sincronización de una base de datos completa, como tablas de prueba o tablas que provocan conmutaciones por error continuas, utilice la siguiente configuración:

source:
    type: mysql
    name: MySQL Source
    hostname: <yourHostname>
    port: 3306
    username: flink
    password: ${secret_values.password}
    tables: test_db.\.*
    # Tables that match this regular expression are not synchronized.
    tables.exclude: test_db.table1
    server-id: 5401-5499
    # (Optional) Synchronize the data of tables created in the incremental phase.
    scan.binlog.newly-added-table.enabled: true
    # (Optional) Synchronize table comments and column comments.
    include-comments.enabled: true
    # (Optional) Assign unbounded chunks first to prevent possible TaskManager out-of-memory errors.
    scan.incremental.snapshot.unbounded-chunk-first.enabled: true
    # (Optional) Enable parse filtering to accelerate reads.
    scan.only.deserialize.captured.tables.changelog.enabled: true

  sink:
    type: maxcompute
    name: MaxComputeSink
    access-id: ${your_accessId}
    access-key: ${your_accessKey}
    endpoint: ${your_maxcompute_endpoint}
    project: ${your_project}
    buckets-num: 8

  pipeline:
    name: MySQL to MaxCompute Pipeline

Habilitar el modo EVOLVE

El modo EVOLVE mantiene el esquema de la tabla de destino estrictamente consistente con el esquema de la tabla de origen, e incluye operaciones como eliminar campos y eliminar tablas. En este modo, si la tabla de destino no aplica todos los eventos de cambio de esquema, el trabajo podría generar una conmutación por error sin posibilidad de recuperación automática. A continuación se muestra un ejemplo de configuración del trabajo:

source:
    type: mysql
    name: MySQL Source
    hostname: <yourHostname>
    port: 3306
    username: flink
    password: ${secret_values.password}
    tables: test_db.test_source_table
    server-id: 5401-5499
    # (Optional) Synchronize the data of tables created in the incremental phase.
    scan.binlog.newly-added-table.enabled: true
    # (Optional) Synchronize table comments and column comments.
    include-comments.enabled: true
    # (Optional) Assign unbounded chunks first to prevent possible TaskManager out-of-memory errors.
    scan.incremental.snapshot.unbounded-chunk-first.enabled: true
    # (Optional) Enable parse filtering to accelerate reads.
    scan.only.deserialize.captured.tables.changelog.enabled: true

  sink:
    type: maxcompute
    name: MaxComputeSink
    access-id: ${your_accessId}
    access-key: ${your_accessKey}
    endpoint: ${your_maxcompute_endpoint}
    project: ${your_project}
    buckets-num: 8

  pipeline:
    name: MySQL to MaxCompute Pipeline
    schema.change.behavior: evolve

Ejemplos

API de SQL

Tabla de origen

Leer todos los datos de una partición

Lea todos los datos de la partición especificada por partition:

CREATE TEMPORARY TABLE odps_source (
  cid VARCHAR,
  rt DOUBLE
) WITH (
  'connector' = 'odps',
  'endpoint' = '<yourEndpointName>',
  'project' = '<yourProjectName>',
  'tableName' = '<yourTableName>',
  'accessId' = '${secret_values.ak_id}',
  'accessKey' = '${secret_values.ak_secret}',
  'partition' = 'ds=201809*'
);

CREATE TEMPORARY TABLE blackhole_sink (
  cid VARCHAR,
  invoke_count BIGINT
) WITH (
  'connector' = 'blackhole'
);

INSERT INTO blackhole_sink
SELECT
   cid,
   COUNT(*) AS invoke_count
FROM odps_source GROUP BY cid;

Leer datos incrementales

Lea los datos a partir de la partición especificada por startPartition y supervise continuamente las particiones nuevas:

CREATE TEMPORARY TABLE odps_source (
  cid VARCHAR,
  rt DOUBLE
) WITH (
  'connector' = 'odps',
  'endpoint' = '<yourEndpointName>',
  'project' = '<yourProjectName>',
  'tableName' = '<yourTableName>',
  'accessId' = '${secret_values.ak_id}',
  'accessKey' = '${secret_values.ak_secret}',
  'startPartition' = 'yyyy=2018,MM=09,dd=05' -- Start reading from the 20180905 partition.
);

CREATE TEMPORARY TABLE blackhole_sink (
  cid VARCHAR,
  invoke_count BIGINT
) WITH (
  'connector' = 'blackhole'
);

INSERT INTO blackhole_sink
SELECT cid, COUNT(*) AS invoke_count
FROM odps_source GROUP BY cid;

Tabla de destino

Escribir en una partición estática

Escriba en la partición especificada por partition:

CREATE TEMPORARY TABLE datagen_source (
  id INT,
  len INT,
  content VARCHAR
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE odps_sink (
  id INT,
  len INT,
  content VARCHAR
) WITH (
  'connector' = 'odps',
  'endpoint' = '<yourEndpoint>',
  'project' = '<yourProjectName>',
  'tableName' = '<yourTableName>',
  'accessId' = '${secret_values.ak_id}',
  'accessKey' = '${secret_values.ak_secret}',
  'partition' = 'ds=20180905' -- Write to partition 20180905.
);

INSERT INTO odps_sink
SELECT
  id, len, content
FROM datagen_source;

Escribir en particiones dinámicas

Escriba los datos en las particiones determinadas en tiempo de ejecución por los valores de la columna ds:

CREATE TEMPORARY TABLE datagen_source (
  id INT,
  len INT,
  content VARCHAR,
  c TIMESTAMP
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE odps_sink (
  id  INT,
  len INT,
  content VARCHAR,
  ds VARCHAR -- Dynamic partition column.
) WITH (
  'connector' = 'odps',
  'endpoint' = '<yourEndpoint>',
  'project' = '<yourProjectName>',
  'tableName' = '<yourTableName>',
  'accessId' = '${secret_values.ak_id}',
  'accessKey' = '${secret_values.ak_secret}',
  'partition' = 'ds' -- Omit the value; data is routed to partitions based on the ds field.
);

INSERT INTO odps_sink
SELECT
   id,
   len,
   content,
   DATE_FORMAT(c, 'yyMMdd') as ds
FROM datagen_source;

Tabla de dimensiones

Clave de valor único

Especifique una clave primaria cuando cada clave se asigne exactamente a una fila:

CREATE TEMPORARY TABLE datagen_source (
  k INT,
  v VARCHAR
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE odps_dim (
  k INT,
  v VARCHAR,
  PRIMARY KEY (k) NOT ENFORCED  -- Specify the primary key.
) WITH (
  'connector' = 'odps',
  'endpoint' = '<yourEndpoint>',
  'project' = '<yourProjectName>',
  'tableName' = '<yourTableName>',
  'accessId' = '${secret_values.ak_id}',
  'accessKey' = '${secret_values.ak_secret}',
  'partition' = 'ds=20180905',
  'cache' = 'ALL'
);

CREATE TEMPORARY TABLE blackhole_sink (
  k VARCHAR,
  v1 VARCHAR,
  v2 VARCHAR
) WITH (
  'connector' = 'blackhole'
);

INSERT INTO blackhole_sink
SELECT k, s.v, d.v
FROM datagen_source AS s
INNER JOIN odps_dim FOR SYSTEM_TIME AS OF PROCTIME() AS d ON s.k = d.k;

Clave de varios valores

Omita la clave primaria cuando una clave pueda asignarse a varias filas:

CREATE TEMPORARY TABLE datagen_source (
  k INT,
  v VARCHAR
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE odps_dim (
  k INT,
  v VARCHAR
  -- No primary key needed for multi-value lookups.
) WITH (
  'connector' = 'odps',
  'endpoint' = '<yourEndpoint>',
  'project' = '<yourProjectName>',
  'tableName' = '<yourTableName>',
  'accessId' = '${secret_values.ak_id}',
  'accessKey' = '${secret_values.ak_secret}',
  'partition' = 'ds=20180905',
  'cache' = 'ALL'
);

CREATE TEMPORARY TABLE blackhole_sink (
  k VARCHAR,
  v1 VARCHAR,
  v2 VARCHAR
) WITH (
  'connector' = 'blackhole'
);

INSERT INTO blackhole_sink
SELECT k, s.v, d.v
FROM datagen_source AS s
INNER JOIN odps_dim FOR SYSTEM_TIME AS OF PROCTIME() AS d ON s.k = d.k;

API de DataStream

Importante
  • Para usar la API de DataStream con MaxCompute, configure un conector de DataStream. Consulte Integrate DataStream connectors.

  • VVR 6.0.6+ admite la depuración local de programas de DataStream con el conector de MaxCompute durante un máximo de 30 minutos. Las sesiones que superan los 30 minutos finalizan con un error. Consulte Depurar conectores de forma local.

  • No se admite la lectura desde una tabla Delta de MaxCompute (una tabla creada con una clave primaria y transactional=true).

Declare la tabla de MaxCompute mediante SQL y luego acceda a ella a través de la API de Table o la API de DataStream.

Conectarse a la tabla de origen

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tEnv = StreamTableEnvironment.create(env);
tEnv.executeSql(String.join(
    "\n",
    "CREATE TEMPORARY TABLE IF NOT EXISTS odps_source (",
    "  cid VARCHAR,",
    "  rt DOUBLE",
    ") WITH (",
    "  'connector' = 'odps',",
    "  'endpoint' = '<yourEndpointName>',",
    "  'project' = '<yourProjectName>',",
    "  'tableName' = '<yourTableName>',",
    "  'accessId' = '<yourAccessId>',",
    "  'accessKey' = '<yourAccessPassword>',",
    "  'partition' = 'ds=201809*'",
    ")");
DataStream<Row> source = tEnv.toDataStream(tEnv.from("odps_source"));
source.print();
env.execute("odps source");

Conectarse al destino

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tEnv = StreamTableEnvironment.create(env);
tEnv.executeSql(String.join(
    "\n",
    "CREATE TEMPORARY TABLE IF NOT EXISTS odps_sink (",
    "  cid VARCHAR,",
    "  rt DOUBLE",
    ") WITH (",
    "  'connector' = 'odps',",
    "  'endpoint' = '<yourEndpointName>',",
    "  'project' = '<yourProjectName>',",
    "  'tableName' = '<yourTableName>',",
    "  'accessId' = '<yourAccessId>',",
    "  'accessKey' = '<yourAccessPassword>',",
    "  'partition' = 'ds=20180905'",
    ")");
DataStream<Row> data = env.fromElements(
    Row.of("id0", 3.),
    Row.of("id1", 4.));
tEnv.fromDataStream(data).insertInto("odps_sink").execute();

Dependencia de Maven

Agregue el conector de DataStream de MaxCompute a su proyecto. Todas las versiones están disponibles en el repositorio central de Maven.

<dependency>
    <groupId>com.alibaba.ververica</groupId>
    <artifactId>ververica-connector-odps</artifactId>
    <version>${vvr-version}</version>
</dependency>

Pasos siguientes