¿Qué hace Construcción de Tablas Iceberg?
Cuándo usar
- Crear o mantener tablas Apache Iceberg en un lakehouse.
- Elegir particionamiento, o evolucionar esquemas/particiones sin necesidad de reescrituras.
- Gestionar instantáneas, viaje en el tiempo, compactación y archivos pequeños.
- NO usar para tareas específicas de Delta (usar
engineering-databricks-pipelines).
Flujo de trabajo
- [ ] Particionar por columnas de filtro de consulta; usar transformaciones de partición ocultas
- [ ] Usar MERGE para upserts idempotentes
- [ ] Programar compactación (rewrite_data_files) para corregir archivos pequeños
- [ ] Expirar instantáneas antiguas + eliminar archivos huérfanos para controlar metadatos/almacenamiento
- [ ] Evolucionar particionamiento/esquema por ID de campo (sin reescritura de datos)
- Particionar en columnas de filtro usando transformaciones de partición ocultas
(
days(ts),bucket(N, id)), para que las consultas poden sin que los usuarios añadan columnas de partición derivadas. - Escrituras idempotentes mediante
MERGE INTOcon clave basada en la clave de negocio. - Compactar regularmente — las escrituras en streaming o en pequeños lotes crean muchos archivos pequeños;
rewrite_data_filesrestaura el rendimiento de lectura. - Mantener metadatos — expirar instantáneas antiguas y eliminar archivos huérfanos, o el historial de instantáneas y el almacenamiento crecerán sin límite.
- Evolucionar libremente — Iceberg rastrea columnas/particiones por ID, por lo que agregar, eliminar, renombrar e incluso cambios en la especificación de particiones no requieren reescritura de datos.
Patrones
Crear con particionamiento oculto + upsert MERGE:
CREATE TABLE lake.db.orders (order_id BIGINT, customer_id BIGINT, amount DECIMAL, ordered_at TIMESTAMP)
USING iceberg PARTITIONED BY (days(ordered_at));
MERGE INTO lake.db.orders t USING staging s ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
Mantenimiento (procedimientos de Spark):
CALL lake.system.rewrite_data_files('db.orders'); -- compactar archivos pequeños
CALL lake.system.expire_snapshots('db.orders', TIMESTAMP '2026-08-01 00:00:00');
CALL lake.system.remove_orphan_files(table => 'db.orders');
Viaje en el tiempo — leer una instantánea anterior para auditoría o recuperación:
SELECT * FROM lake.db.orders VERSION AS OF <snapshot_id>.
Evolución de particiones — ALTER TABLE ... ADD PARTITION FIELD bucket(16, customer_id)
se aplica solo a los nuevos datos; los datos antiguos siguen siendo válidos.
Errores comunes
- Sin compactación en tablas de streaming — la explosión de archivos pequeños perjudica la velocidad de lectura.
- Nunca expirar instantáneas — los metadatos y el almacenamiento crecen sin límite; programa la expiración dentro de tu período de retención de viaje en el tiempo.
- Sobredimensionamiento del particionamiento (p. ej., por hora en volúmenes bajos) — demasiadas particiones diminutas; iguala la granularidad al tamaño de los datos.
- Añadir columnas de partición derivadas explícitas — va en contra del propósito del particionamiento oculto; usa transformaciones.
- Sobrescritura ciega en lugar de MERGE — pierde idempotencia; usa MERGE por clave.
- Eliminar archivos huérfanos con una ventana demasiado corta — puede eliminar archivos que los escritores activos aún necesitan; usa un límite de tiempo seguro.