Apache Paimon admite dos tipos de tablas: tablas de clave primaria y tablas de solo anexión. Cada tipo tiene una semántica distinta para escrituras, actualizaciones y consumo mediante streaming. Elija el tipo que se ajuste a los requisitos de su pipeline de datos.
Selección de un tipo de tabla
|
Escenario |
Configuración recomendada |
|
Sincronización CDC, upserts estándar |
Tabla de clave primaria, motor |
|
Deduplicación donde solo importa el primer registro |
Tabla de clave primaria, motor |
|
Agregación en tiempo real (totales acumulados, seguimiento de máximos/mínimos) |
Tabla de clave primaria, motor |
|
Ensamblaje de tablas anchas desde varios orígenes de streaming |
Tabla de clave primaria, motor |
|
Ingesta de registros, streaming de eventos |
Tabla de solo anexión (escalable) |
|
Reemplazo de cola de mensajes con preservación de orden |
Tabla de cola de anexión |
Tablas de clave primaria
Una tabla de clave primaria requiere una o más claves primarias, las cuales se especifican al crear la tabla. Los registros con las mismas claves primarias se fusionan según el motor de fusión configurado.
CREATE TABLE T (
dt STRING,
shop_id BIGINT,
user_id BIGINT,
num_orders INT,
total_amount INT,
PRIMARY KEY (dt, shop_id, user_id) NOT ENFORCED
) PARTITIONED BY (dt) WITH (
'bucket' = '4'
);
En este ejemplo, la clave de partición es dt, las claves primarias son dt, shop_id y user_id, y la tabla utiliza 4 buckets fijos.
Modos de bucket
Un bucket es la unidad mínima de lectura y escritura en una tabla Paimon. Las particiones (o la tabla completa en el caso de tablas sin particionar) se subdividen en buckets, lo que permite lecturas y escrituras paralelas.
|
Modo |
Configuración |
Notas |
|
Modo de bucket dinámico (predeterminado) |
Omita |
No admite escrituras simultáneas desde varios despliegues de Flink; admite actualizaciones entre particiones |
|
Modo de bucket fijo |
Establezca |
|
Dimensionamiento de buckets: Se recomienda configurar el tamaño total de datos en cada bucket en 2 GB y no especificar un valor superior a 5 GB. Muy pocos buckets limitan el paralelismo de escritura; demasiados generan una cantidad excesiva de archivos pequeños.
Modo de bucket dinámico: cómo se actualizan los datos
Las actualizaciones entre particiones ocurren cuando las claves primarias no incluyen todas las claves de partición. Paimon no puede determinar la partición de destino solo con la clave primaria, por lo que utiliza RocksDB para mantener un mapeo de clave primaria a partición/bucket. En tablas grandes, esto puede reducir significativamente el rendimiento en comparación con el modo de bucket fijo, y la inicialización del despliegue tarda más mientras el mapeo se carga en RocksDB.
El comportamiento de actualización depende del motor de fusión:
deduplicate: elimina el registro existente e inserta uno nuevo en la partición de destino.aggregationopartial-update: actualiza el registro existente en su lugar dentro de la partición actual.first-row: conserva el registro existente y descarta el registro entrante.
Las actualizaciones dentro de la partición ocurren cuando las claves primarias incluyen todas las claves de partición. Paimon puede determinar la partición a partir de la clave primaria, pero no el bucket, por lo que mantiene un índice en memoria que mapea las claves primarias a los buckets. Cada 100 millones de entradas de mapeo consumen aproximadamente 1 GB de memoria heap, la cual se asigna únicamente a las particiones que se están escribiendo activamente.
Modo de bucket dinámico: asignación de buckets
Los nuevos registros se escriben primero en los buckets existentes. Si todos los buckets han alcanzado su capacidad, se crea automáticamente un nuevo bucket.
Configure este comportamiento con los siguientes parámetros en la cláusula WITH:
|
Parámetro |
Descripción |
Valor predeterminado |
|
|
Máximo de registros por bucket |
|
|
|
Recuento inicial de buckets |
Paralelismo del operador Writer |
Modo de bucket fijo: asignación de buckets
De forma predeterminada, Paimon asigna registros a los buckets mediante un hash de los valores de la clave primaria. Para usar un conjunto diferente de columnas, establezca bucket-key en la cláusula WITH. Especifique varias columnas separadas por comas. Las columnas en bucket-key deben ser un subconjunto de las claves primarias.
Por ejemplo, 'bucket-key' = 'c1,c2' enruta los registros según el hash de c1 y c2.
En el modo de bucket fijo, incluya todas las claves de partición en las claves primarias para evitar actualizaciones entre particiones.
Cambio del número de buckets en el modo de bucket fijo
El recuento de buckets determina el paralelismo de lectura y escritura. Para modificarlo en una tabla existente:
Pause todos los despliegues que lean o escriban en la tabla.
-
Cree un script y ejecute la siguiente sentencia SQL para configurar el parámetro de bucket:
ALTER TABLE `<catalog-name>`.`<database-name>`.`<table-name>` SET ('bucket' = '<bucket-num>'); -
Reorganice los datos ejecutando un despliegue por lotes.
Tabla sin particionar: Cree un Blank Batch Draft, pegue el siguiente código SQL, luego haga clic en Deploy y Start: ``
sql INSERT OVERWRITE<catalog-name>.<database-name>.<table-name>SELECT * FROM<catalog-name>.<database-name>.<table-name>;``-
Tabla particionada: Ejecute un proceso por lotes por cada partición que desee reorganizar:
INSERT OVERWRITE `<catalog-name>`.`<database-name>`.`<table-name>` PARTITION (<partition-spec>) SELECT * FROM `<catalog-name>`.`<database-name>`.`<table-name>` WHERE <partition-condition>;Ejemplo — reorganizar la partición donde
dt = '20240312'yhh = '08':INSERT OVERWRITE `<catalog-name>`.`<database-name>`.`<table-name>` PARTITION (dt = '20240312', hh = '08') SELECT * FROM `<catalog-name>`.`<database-name>`.`<table-name>` WHERE dt = '20240312' AND hh = '08';
Una vez que el despliegue por lotes finalice correctamente, reanude los despliegues pausados.
Motores de fusión
Cuando varios registros comparten las mismas claves primarias, Paimon los fusiona según la configuración de merge-engine.
Si su flujo de entrada contiene registros desordenados, configure el parámetro sequence.field para controlar el orden de fusión. Consulte Manejo de datos desordenados .
Manejo de datos desordenados
De forma predeterminada, Paimon fusiona los registros en el orden de entrada; el último registro recibido es el último en fusionarse. Para flujos con registros desordenados, establezca sequence.field en la cláusula WITH. Los registros con las mismas claves primarias se fusionarán entonces en orden ascendente según el valor de la columna especificada.
Tipos de datos compatibles para sequence.field: TINYINT, SMALLINT, INTEGER, BIGINT, TIMESTAMP, TIMESTAMP_LTZ.
Cuando se usa MySQL como origen de entrada con la columna de metadatosop_tcomo campo de secuencia, los pares de cambios UPDATE_BEFORE y UPDATE_AFTER comparten el mismo valor de secuencia. Para garantizar que Paimon procese UPDATE_BEFORE antes que UPDATE_AFTER, establezca'sequence.auto-padding' = 'row-kind-flag'.
Productor de changelog
Una tabla de clave primaria debe generar un changelog completo (que cubra operaciones INSERT, DELETE y UPDATE) para admitir el consumo posterior mediante streaming, de manera similar al binlog de una base de datos. Configure el método de generación con el parámetro changelog-producer.
|
Valor |
Descripción |
Latencia |
Uso de recursos |
Uso recomendado |
|
|
No se genera changelog. |
— |
Mínimo |
No se requiere consumo mediante streaming |
|
|
Pasa los registros de entrada directamente a los consumidores posteriores. |
Mínima |
Mínimo |
La entrada ya contiene un changelog completo, como el binlog de una base de datos. Es la opción más eficiente, ya que no requiere cómputo adicional. |
|
|
Ejecuta una búsqueda contra los resultados de compactación de archivos pequeños para producir un changelog completo. Se activa en cada checkpoint de Flink. |
Nivel de minutos |
Mayor |
Cualquier tipo de entrada; requisitos de latencia a nivel de minutos |
|
|
Genera un changelog después de cada compactación completa de archivos pequeños. |
Hasta varias horas |
Menor que |
Cualquier tipo de entrada; se acepta una latencia mayor |
Para full-compaction, establezca 'full-compaction.delta-commits' = '<num>' para activar la compactación completa después de cada <num> checkpoints de Flink. La compactación completa consume muchos recursos; configure el intervalo entre 30 minutos y 1 hora.
De forma predeterminada, Paimon genera un registro de changelog incluso cuando el valor actualizado es idéntico al anterior. Para suprimir estos registros sin cambios, establezca'changelog-producer.row-deduplicate' = 'true'. Esta opción solo aplica alookupyfull-compaction, y requiere cómputo adicional para comparar los valores antes y después, así que habilítela solo cuando se espere una gran cantidad de registros innecesarios.
Tablas de solo anexión
Una tabla de solo anexión no tiene claves primarias y solo acepta operaciones INSERT en modo streaming. Utilice este tipo de tabla para cargas de trabajo que no requieren actualizaciones mediante streaming, como la sincronización de datos de registros.
CREATE TABLE T (
dt STRING,
order_id BIGINT,
item_id BIGINT,
amount INT,
address STRING
) PARTITIONED BY (dt) WITH (
'bucket' = '-1'
);
Subtipos
|
Subtipo |
Configuración |
Características |
|
Tabla escalable de anexión |
|
Alto rendimiento de escritura; no requiere particionamiento por hash; admite ordenamiento de datos; configuración flexible de paralelismo; admite conversión directa desde tablas Hive; compactación de archivos completamente asíncrona; el orden de consumo difiere del orden de escritura; posible sesgo de datos cuando el paralelismo del origen equivale al paralelismo de escritura |
|
Tabla de cola de anexión |
|
Preserva el orden por bucket; latencia de varios minutos; equivalente a una partición de tema de Kafka o al número de shards en una instancia de ApsaraMQ for MQTT |
Asignación de buckets
Tabla escalable de anexión: Los datos se escriben directamente en una sola partición en paralelo. Se ignora el concepto de bucket y no se requiere particionamiento por hash, lo que maximiza el rendimiento de escritura.
Tabla de cola de anexión: De forma predeterminada, los registros se asignan a los buckets según los valores de todas las columnas del registro de datos. Para controlar la asignación, establezca bucket-key en la cláusula WITH con una lista de nombres de columna separados por comas.
Por ejemplo, 'bucket-key' = 'c1,c2' enruta los registros según el hash de c1 y c2.
Especifique bucket-key para reducir el cómputo de asignación de buckets y mejorar la eficiencia de escritura.
Orden de consumo de datos
Tabla escalable de anexión: Los registros pueden consumirse en un orden diferente al de escritura.
Tabla de cola de anexión: Los registros dentro de cada bucket se consumen en el orden de escritura. Para registros en distintas particiones o buckets:
Dos registros de distintas particiones: si
'scan.plan-sort-partition' = 'true', se consume primero el registro con el menor valor de partición; de lo contrario, se consume primero el registro de la partición creada anteriormente.Dos registros de la misma partición, mismo bucket: se consume primero el registro escrito anteriormente.
Dos registros de la misma partición, distintos buckets: no se garantiza el orden de consumo porque distintos buckets pueden procesarse simultáneamente.
Pasos siguientes
Para crear un catálogo y una tabla Paimon, consulte Gestión de catálogos Paimon.
Para optimizar el rendimiento de tablas de clave primaria, consulte Optimización del rendimiento.