- Experimento de comparación de rendimiento procesando datos Delta Lake de 650GB almacenados en S3 con Polars, DuckDB, Daft y Spark en un entorno de nodo único
- Verificación de si cada motor puede procesar datos de gran volumen en una instancia EC2 con 32GB de memoria, explorando la viabilidad del nodo único frente a Spark basado en clúster
- DuckDB tardó 16 minutos, Polars 12 minutos, Daft 50 minutos y PySpark más de 1 hora, confirmando una posibilidad real de procesamiento incluso en un solo nodo
- Polars no soporta Deletion Vector, mientras que solo DuckDB sí lo soporta, lo que marca una diferencia en la compatibilidad con Lake House
- En conjunto, se demuestra que los frameworks de nodo único pueden procesar grandes volúmenes de datos incluso con hardware de bajo costo, lo que plantea la necesidad de reconsiderar la dependencia de la computación distribuida
Fatiga de clúster y alternativa de nodo único
- A medida que crecen el costo y la complejidad de operar clústeres Lake House basados en SaaS, se menciona el fenómeno de la “fatiga de clúster” (
cluster fatigue)
- Antes se usaba Spark porque no había alternativas reales aparte de Pandas, pero con la aparición de DuckDB, Polars y Daft (D.P.D.) se amplía la viabilidad del procesamiento en un solo nodo
- D.P.D. permite procesar datasets más grandes que la memoria (LTM) y realizar operaciones de alta velocidad
- El artículo plantea dos opciones, distribuida y no distribuida, y enfatiza el concepto de “Single Node Rebellion”
Configuración del entorno de prueba
- Se creó una tabla Delta Lake en S3 y se almacenaron aproximadamente 650GB de datos (el objetivo era 1TB, pero se detuvo antes)
- Se ejecutaron DuckDB, Polars y Daft en una instancia EC2 (32GB RAM, 16 CPU) y luego se compararon con Spark
- Los datos eran simulados con forma de publicaciones de redes sociales; se generaron como diccionarios de Python, se convirtieron en un Daft DataFrame y luego se guardaron como archivos Parquet
- Después, los archivos Parquet se convirtieron en una tabla Delta Lake en Databricks, con particiones por año y mes
- Excluyendo el log de Delta, se confirmó un volumen de aproximadamente 650GB de datos
Restricciones de memoria y necesidad de streaming
- Como había que procesar 650GB de datos en un solo nodo (32GB de memoria), se plantea la necesidad de ejecutar consultas en modo streaming
- Citando un issue de GitHub de Polars, se menciona un caso que solicita funcionalidad de escritura en streaming para Iceberg
- Se subraya la necesidad de que frameworks modernos como Polars y DuckDB ofrezcan soporte nativo para leer y escribir formatos Lake House en modo streaming
Resultados de prueba por motor
- DuckDB
- Único con soporte para Deletion Vector
- Procesó exitosamente 650GB de datos en una máquina Linux con 32GB en solo 16 minutos
- Código simple y archivo de resultados generado correctamente
- Polars
- No soporta Deletion Vector, por lo que tiene limitaciones en entornos Lake House
- Requiere usar la Lazy API (Scan/Sink)
- Completó el procesamiento en 12 minutos, más rápido que DuckDB
- Daft
- Basado en Rust, con buena experiencia de uso, pero fue el más lento con 50 minutos de procesamiento
- Se confirmó un funcionamiento estable en tareas relacionadas con Iceberg
- PySpark (Databricks Single Node)
- Más de 1 hora de ejecución, sin tuning
- Menor eficiencia frente a motores de nodo único
- El objetivo del experimento no era tanto la velocidad como verificar la viabilidad del nodo único
Conclusión e implicaciones
- El experimento demuestra que los frameworks de nodo único pueden procesar grandes volúmenes de datos Lake House
- Incluso con hardware de bajo costo, se logra un tiempo de ejecución razonable y una estructura de código simple
- DuckDB, Polars y Daft ofrecen rendimiento práctico incluso sin clúster distribuido
- Se muestra que la computación distribuida no es la única solución posible, lo que invita a repensar la arquitectura moderna de Lake House
- El concepto de “Single Node Rebellion” resalta la posibilidad de un enfoque de ingeniería de datos más costo-eficiente
1 comentarios
Comentarios de Hacker News
Daft es un motor de procesamiento de datos de alto rendimiento para cargas de trabajo de IA, y funciona tanto en un solo nodo como en entornos distribuidos
Con este benchmark encontramos mucho margen de mejora en paralelismo y pipelining. En particular, había bastante por optimizar en el lector de deltalake y en el operador groupby
Planeamos reflejar estas mejoras en futuros lanzamientos; pueden ver más detalles en GitHub, Twitter y LinkedIn
Si Daft les parece interesante, pueden probarlo directamente con
pip install daftEn vez de usar tooling excesivo, simplemente usen herramientas GNU
Por cierto, es un artículo viejo pero sigue siendo interesante — command-line tools can be 235x faster than your Hadoop cluster
Si intentas agregar 650GB de datos JSON con herramientas CLI, va a ser difícil igualar el rendimiento de procesamiento paralelo de DuckDB o ClickHouse. También lo intenté con GNU Parallel, pero había límites
En la práctica, necesitas catálogos de datos y trabajo basado en clústeres
En vez de Delta o Iceberg, consulto archivos Parquet directamente recorriéndolos
Descargo resultados consultados en BigQuery como archivos Parquet locales (de alrededor de 1GB cada uno) y los analizo con DuckDB. Son datos mucho más grandes que la RAM, pero funciona bien
También comparo la diferencia de rendimiento en agregaciones entre BigQuery y DuckDB, y a veces divido el trabajo entre ambos motores. Esa combinación es una parte divertida de la ingeniería de datos
Con el máximo de 10Gbps de una instancia c5.4xlarge, leer 650GB desde S3 tomaría al menos 9 minutos
Pequeñas diferencias en cómo se programó el I/O probablemente afectaron mucho el resultado
De hecho, podría ser más económico usar una instancia más grande y terminar antes
El almacenamiento NVMe es mucho más rápido que S3, y una CPU local de 8 a 16 núcleos podría rendir mejor que la nube
S3 es un gran producto, pero no se compara con el rendimiento del almacenamiento local
La distribución del tamaño de archivos o el sesgo en las llamadas API probablemente fueron variables más importantes
Estoy totalmente de acuerdo con que “una instancia más grande podría terminar saliendo más barata”
Spark es adecuado para datasets grandes de múltiples etapas, y cuando usas S3 como backend, el cuello de botella de red aparece directamente como costo
El rendimiento de un solo nodo de DuckDB/Polars es impresionante, pero esto es como poner a competir un avión en la pista contra una motocicleta
Por diferencias como esta, mucha gente termina cansándose del cómputo distribuido
Si identificas los límites de recursos y expresas el rendimiento real como proporción de ese límite, todo queda mucho más claro
Está bien que hayan probado varios sistemas, pero me gustaría que trataran en serio las consultas más grandes que la memoria
DuckDB es fuerte en streaming fuera de memoria, pero Polars todavía está verde en ese aspecto
La configuración por defecto de S3 no impide las lecturas paralelas, así que al final es muy probable que el cuello de botella sea el ancho de banda de red de la VM
ClickHouse fue lo más rápido, y DuckDB fue el mejor en simplicidad y estabilidad
Flink y PySpark fueron de 3 a 5 veces más lentos, y Dask y Ray también fueron demasiado lentos
Ahora recomiendo empezar con DuckDB o ClickHouse para la mayoría de las cargas de trabajo. Mi estrategia por defecto cuando Pandas se queda corto es reemplazarlo con DuckDB
Incluso con una librería de un solo nodo, 1TB se puede manejar sin problema, y recién a partir de más de 10TB tiene sentido pasar a Spark
Issue relacionado
Pero en muchos casos se puede resolver con herramientas mejores
Hace tiempo, un ingeniero junior tardó 18 horas procesando cientos de JSON de 5GB con concatenación de strings en Python,
pero al cambiarlo por herramientas sencillas de consola y multiprocessing, bajó a 35 minutos
La clave está en elegir la herramienta adecuada
Su mantenimiento y costo de ejecución son muy bajos, y es una herramienta con gran relación costo-beneficio
Para resolver el problema de que se generen demasiados archivos Parquet al escribir lotes pequeños, DuckLake los guarda inline en un DBMS (como Postgres)
Recién hace poco apareció la capacidad de volver a escribirlos como Parquet, pero todavía necesita estabilizarse
Documentación relacionada
Tienes que expresar el catálogo en una base de datos SQL, pero justamente una de las ventajas de Parquet es evitar esa complejidad
Si el catálogo también fuera basado en Parquet, podría convertirse en un formato autoarrancable