Global Trend Radar
Dev.to US tech 2026-05-08 07:19

DuckLake 1.0: SQLにファイルカタログを移行し、Icebergより926倍の速度を約束するデータレイクフォーマット

原題: DuckLake 1.0: el formato de data lake que mueve el catálogo de archivos a SQL y promete 926 más velocidad que Iceberg

元記事を開く →

分析結果

カテゴリ
エネルギー
重要度
52
トレンドスコア
14
要約
DuckLake 1.0は、ファイルカタログをSQLに移行する新しいデータレイクフォーマットです。この新技術は、従来のIcebergと比較して926倍の速度向上を実現するとされています。これにより、データ処理の効率が大幅に向上し、データ分析や管理がより迅速に行えるようになります。
キーワード
El 13 de abril de 2026 , DuckDB Labs liberó la versión 1.0 de DuckLake , un formato de data lake con backward-compatibility garantizada que rompe con la convención de los últimos cinco años en lakehouses: en lugar de almacenar el catálogo de metadatos como una pila de archivos JSON dispersos en object storage —el patrón que usan Apache Iceberg , Delta Lake y Apache Hudi —, DuckLake lo guarda en una base de datos relacional . La consecuencia técnica es directa, y los benchmarks reportados por el propio equipo son contundentes: 926× más rápido en consultas y 105× más rápido en ingesta frente a Iceberg en cargas de trabajo con muchas escrituras pequeñas, según declaraciones de Pedro Holanda , ingeniero principal de DuckDB Labs, recogidas por The Register . InfoQ cubrió el lanzamiento el 2 de mayo , firmado por Renato Losio. El anuncio oficial en ducklake.select lista las cinco features principales: data inlining , sorted tables , bucket partitioning , soporte completo para tipos GEOMETRY y VARIANT , y deletion vectors compatibles con Iceberg v3 . El repositorio público en GitHub ya está disponible bajo licencia open source y los clientes para Apache DataFusion , Apache Spark , Trino y Pandas son operativos al día del release. MotherDuck ofrece una versión hosteada que gestiona la base de datos del catálogo y el storage subyacente. Este artículo explica, en términos accesibles para ingenieros de datos y devs que están evaluando lakehouses para 2026, qué es DuckLake exactamente, qué problema concreto resuelve, cómo se integra con el stack actual, y cuándo conviene preferirlo sobre Iceberg o Delta Lake. La cobertura es continuación natural de la línea editorial dev del blog —los posts recientes sobre Bun→Rust, pnpm 11 y Cloudflare Agents Week— en una pieza que toca el lado de datos que estaba sub-cubierto. El problema que ataca: el "small file problem" en lakehouses Los lakehouses modernos — Iceberg desde Netflix en 2017, Delta Lake desde Databricks en 2019— resolvieron un problema real: dieron transacciones ACID sobre data lakes que antes eran simplemente "carpetas de archivos Parquet sin orden". Para hacerlo, agregaron una capa de metadata que registra qué archivos componen una tabla en cada momento, qué snapshots existen, qué columnas hay, qué particiones aplican. Esa metadata —archivos JSON, Avro o manifiestos específicos del formato— se guarda junto a los datos en object storage como S3, R2 o GCS. El problema aparece cuando el patrón de uso no es "ingesta batch grande cada hora". Si un workload incluye escrituras pequeñas frecuentes —insertar una fila, actualizar diez registros, borrar una tupla— el resultado es que cada operación genera al menos un archivo Parquet nuevo (Parquet está optimizado para millones de filas, no para una sola) más uno o varios archivos de metadata para registrar el cambio. Hannes Mühleisen , cofundador y CEO de DuckDB Labs, lo describió a The Register con esta cita: "You make a small change to your table, adding a single row, and it affects data lake performance because... a new file has to be written... and then a bunch of metadata." El costo se acumula. Tras pocos miles de escrituras pequeñas un usuario termina con decenas de miles de archivos diminutos y consultas que tienen que listar y leer todo ese ruido para responder a una pregunta simple. Las "compaction jobs" que se corren periódicamente para fusionar archivos pequeños en archivos grandes ayudan, pero introducen su propio mantenimiento operacional. Y los object stores cobran por requests: 100.000 archivos pequeños cuestan más que 1.000 archivos grandes con el mismo volumen total de datos. La solución de DuckLake: catálogo en SQL, datos en Parquet DuckLake invierte la división. Los datos se siguen guardando como Parquet en object storage —compatibilidad total con el ecosistema existente—, pero el catálogo, los snapshots, los metadatos de schema y la lista de archivos se guardan en una base de datos relacional estándar . Los backends soportados oficialmente al día del release 1.0 son tres: DuckDB (sí, DuckDB puede ser su propio catálogo), PostgreSQL y SQLite . Esto resuelve el problema de los archivos pequeños de raíz. Cuando llega una escritura de 10 filas, DuckLake no escribe un Parquet nuevo . Acumula esa escritura dentro de la base de datos del catálogo —que está optimizada precisamente para muchas operaciones pequeñas con ACID y transacciones reales—, y solo cuando la acumulación cruza un threshold (default: 10 filas, configurable) descarga las filas a Parquet en object storage. La feature se llama data inlining y es una de las cinco piezas de la 1.0. -- Crear una tabla DuckLake usando PostgreSQL como catálogo ATTACH 'postgres://user:pwd@host/dbname' AS catalog ( TYPE POSTGRES ); USE catalog ; CREATE TABLE events ( id BIGINT , ts TIMESTAMP , user_id VARCHAR , payload VARIANT ); -- Inserts pequeños quedan inlineados en el catálogo INSERT INTO events VALUES ( 1 , NOW (), 'user-42' , '{"action": "click"}' ); INSERT INTO events VALUES ( 2 , NOW (), 'user-17' , '{"action": "view"}' ); -- Cuando la acumulación supera el threshold, descarga a Parquet -- Sin que el usuario tenga que pensarlo La diferencia operativa para el usuario es ninguna : el SQL es estándar, los datos viven en S3/R2/GCS como siempre, las consultas se responden con Parquet cuando los datos ya están descargados o desde el catálogo cuando todavía no. La diferencia de performance, en cargas de trabajo con muchas escrituras pequeñas, es del orden de los dos órdenes de magnitud . Las cinco features de la 1.0 en detalle Data inlining El threshold por defecto es 10 filas . Por debajo de eso, las filas viven en la tabla del catálogo. Por encima, se descargan a Parquet. El usuario puede configurar el threshold para subir o bajar la frontera según el patrón de carga: cargas con muchas escrituras pequeñas se benefician de un threshold alto (digamos 1.000), mientras que cargas con muy pocas escrituras pequeñas no necesitan inline en absoluto. Sorted tables DuckLake permite declarar el orden lógico de las filas dentro de cada archivo Parquet, usando ya sea nombres de columnas o expresiones SQL arbitrarias : CREATE TABLE sales ( region VARCHAR , sale_date DATE , amount DECIMAL ) SET SORTED BY ( region ASC , sale_date DESC ); El motor aprovecha el orden para hacer file pruning y row-group pruning en consultas filtradas. Para una consulta que filtre por region = 'eu' y sale_date > '2026-01-01' , el motor lee solo los archivos y row-groups que contienen esas combinaciones, sin escanear el resto. Bucket partitioning Particionado basado en hash con murmur3 —el mismo algoritmo que usa Iceberg, lo cual permite migración bidireccional sin reorganizar archivos—. Útil para columnas de alta cardinalidad como user_id o session_id donde el particionado por valor (range) sería ineficiente porque hay millones de valores distintos. Tipos GEOMETRY y VARIANT GEOMETRY brinda soporte completo para datos espaciales, sin necesidad de extensiones externas como PostGIS para queries geoespaciales básicas. VARIANT es el tipo equivalente a JSON pero con encoding binario y mejor performance. La diferencia importa cuando se almacenan campos semiestructurados —payloads de eventos, metadata flexible— a escala: VARIANT se serializa más rápido y se filtra más rápido que JSON parseado on-the-fly. Deletion vectors compatibles con Iceberg v3 DuckLake soporta deletion vectors —el mecanismo donde, en vez de reescribir un archivo Parquet entero al borrar filas, se mantiene un bitmap separado que marca qué filas están eliminadas—. La implementación usa archivos Puffin (formato binario para metadata extensible que Iceberg v3 también usa), lo que mantiene compatibilidad bidireccional con tablas Iceberg. Comparativa contra Iceberg y Delta Lake Dimensión Iceberg / Delta DuckLake 1.0 Catálogo de metadatos Archivos JSON / Avro en object storage RDBMS (DuckDB, Postgres, SQLite) Manejo de escrituras pequeñas Crea archivos por operación Data inlining hasta threshold Compaction jobs Operacionalmente requeridos Automáticos vía descarga periódica Backend de datos Parquet en S3/R2/GCS Parquet en S3/R2/GCS (igual) Soporte SQL multi-cliente Sí (Trino, Spark, etc.) Sí (DataFusion, Spark, Trino, Pandas) Time-travel Sí Sí, vía ducklake_table_changes() Branching de datasets No nativo Planeado para v2.0 Performance escrituras pequeñas Baseline ~105× faster (Holanda) Performance consultas Baseline ~926× faster (Holanda) Es importante calibrar los números. 926× más rápido en consultas no es la diferencia que vas a ver en un benchmark cualquiera ; es el límite superior medido por el equipo en cargas con muchísimos archivos pequeños donde Iceberg sufre desproporcionadamente. En cargas batch tradicionales —ingesta horaria de millones de filas, sin updates intermedios— la diferencia se reduce a factores cercanos a la paridad , y Iceberg sigue siendo competitivo. La pregunta operativa para un equipo no es "qué formato es más rápido en abstracto" sino "qué formato encaja mejor con mi patrón de uso real". Cómo empezar: implementación paso a paso Para un equipo que quiere evaluar DuckLake hoy, el camino mínimo es directo. Caso A: solo DuckDB local + filesystem # Instalar DuckDB 1.5.2+ que incluye la extensión DuckLake curl https://install.duckdb.org | sh # Lanzar shell interactiva duckdb -- Crear un DuckLake con catálogo SQLite + datos en filesystem local ATTACH 'ducklake:/tmp/my_catalog.sqlite' AS lake ( DATA_PATH '/tmp/data/' ); USE lake ; CREATE TABLE customers ( id INT , name VARCHAR , country VARCHAR ); INSERT INTO customers VALUES ( 1 , 'Ana' , 'SV' ), ( 2 , 'Bob' , 'US' ); SELECT * FROM customers ; -- Time-travel: ver cambios en la tabla SELECT * FROM ducklake_table_changes ( 'customers' ); Caso B: producción con catálogo PostgreSQL + datos en S3 / R2 -- Catalogo en Postgres, datos en R2 de Cloudflare ATTACH 'ducklake:postgres://catalog_user:[email protected]/lake_catalog' AS lake ( DATA_PATH 's3://my-bucket/lake/' , ENDPOINT 'https://