- F3 (Future-proof File Format) es un formato de almacenamiento columnar open source de próxima generación, con interoperabilidad, extensibilidad y eficiencia como principios centrales de diseño, y busca eliminar la necesidad de crear un formato nuevo cada vez que cambian los entornos de procesamiento y cómputo de datos
- Cada archivo F3 tiene una estructura autodescriptiva (self-describing), e integra no solo los datos y metadatos, sino también un decodificador binario de WebAssembly (Wasm), lo que garantiza compatibilidad en todas las plataformas incluso sin un decodificador nativo
- Ofrece un layout de almacenamiento eficiente con técnicas modernas de codificación, como compresión escalonada y decodificación vectorizada, y mejora los problemas de layout de Parquet y ORC al separar las unidades de I/O, codificación y diccionario
- Mediante una API de decodificación basada en plugins y un mecanismo de embebido de Wasm, los desarrolladores pueden agregar fácilmente nuevos esquemas de codificación, y todos los archivos pueden leerse sin importar la versión de la biblioteca, resolviendo así los problemas de interoperabilidad de Parquet
- Los resultados de la evaluación demostraron la eficiencia del layout de almacenamiento de F3 y las ventajas de la decodificación basada en Wasm; la sobrecarga de almacenamiento es mínima, de nivel kilobytes, y la caída de rendimiento de la decodificación Wasm frente a la nativa se mantiene en un rango aceptable del 10 al 30%
Contexto y motivación
Limitaciones de los formatos columnarios existentes
- Parquet y ORC fueron desarrollados a inicios de la década de 2010 para sistemas de análisis de datos como Hive, Impala y Spark, y permitieron compartir datos entre data warehouses y data lakes
- Diez años después, las investigaciones muestran que estos formatos son insuficientes para el análisis de datos moderno, porque se basaron en suposiciones obsoletas sobre el rendimiento del hardware y en suposiciones sobre los patrones de acceso de las cargas de trabajo al momento de su diseño
- En la última década, el rendimiento del almacenamiento y la red mejoró varias decenas de veces, pero el del CPU no lo hizo al mismo ritmo, por lo que los sistemas ahora sufren cuellos de botella en cómputo más que en I/O
- Con el auge de los data lakes, cada vez más datos se almacenan en almacenamiento en la nube de alto ancho de banda y alta latencia, como Amazon S3
- Las aplicaciones ya no almacenan solo datos tabulares con pocas columnas. En cargas de trabajo de ML es común almacenar tablas anchas con miles de columnas, embeddings vectoriales de alta dimensionalidad y blobs de gran tamaño como imágenes y video
- También ha aumentado la necesidad de realizar acceso aleatorio o actualizaciones, pero los formatos existentes no se adaptan bien a esos patrones de uso
- Los avances recientes en compresión, indexación y filtrado intentan resolver estas deficiencias, pero los formatos de archivo existentes no fueron diseñados para ser fácilmente extensibles
- Aunque se agreguen nuevas funciones, es difícil esperar que las múltiples implementaciones en distintos lenguajes de las bibliotecas de Parquet y ORC estén actualizadas
- Los sistemas que usan bibliotecas antiguas pueden no ser capaces de decodificar el contenido de archivos nuevos, por lo que la mayoría de los sistemas termina soportando solo el mínimo común denominador para evitar problemas de interoperabilidad
Aparición de nuevos formatos de archivo y sus límites
- Para superar esto, han surgido propuestas de formatos de archivo completamente nuevos, como Meta Nimble, Lance, TSFile, Bullion y BtrBlocks
- Sin embargo, también cometen los mismos errores que sus predecesores
- Están diseñados a partir de supuestos sobre hardware y cargas de trabajo actuales
- No fomentan una extensibilidad sencilla que permita incorporar nuevas funciones sin romper la interoperabilidad con despliegues existentes
- Incluso si uno de ellos reemplazara a Parquet u ORC como formato dominante, dentro de 10 años aparecería el mismo problema: habría que crear otro formato más para corregir sus limitaciones
El enfoque de F3
- F3 busca lograr al mismo tiempo interoperabilidad, extensibilidad y eficiencia
- El núcleo de F3 define tres especificaciones principales:
- Los metadatos del contenido del archivo
- El layout de agrupamiento físico de los datos codificados dentro del archivo
- Una API de acceso a datos independiente del esquema de codificación de los datos
- El esquema de metadatos de F3 minimiza los datos necesarios para recuperar subconjuntos de columnas de una tabla
- F3 elimina el concepto integral de row group de Parquet y resuelve los problemas de layout separando las unidades de I/O, codificación y diccionario
- También integra métodos modernos como la compresión escalonada y la decodificación vectorizada
Resumen de F3
Estructura general
- Un archivo F3 se compone de una sección de metadatos y una sección de datos
- Sección de metadatos: OptionalData (OptData), Column Metadata (ColMetadata), Footer, Postscript
- Sección de datos: compuesta por Row Groups (RG), que contienen los datos reales
- F3 adopta el mismo layout PAX que Parquet y ORC
- Sin embargo, F3 presenta varias diferencias clave frente a los formatos existentes:
- Los metadatos eliminan la sobrecarga de deserialización (resolviendo un problema de Parquet/ORC)
- La unidad física de I/O (IOUnit) se separa del row group lógico, lo que permite ajustar el tamaño de la IOUnit de forma independiente según el medio de almacenamiento
- El alcance de la codificación por diccionario se separa del row group lógico, lo que permite determinar el alcance más efectivo para cada columna
- Cada IOUnit está formada por varias Encoding Units (EncUnit), y la EncUnit es la unidad mínima para codificación y decodificación
Mecanismos de interoperabilidad y extensibilidad
- F3 expone una API pública que define cómo una implementación debe decodificar los datos comprimidos dentro del archivo
- Los métodos de codificación se tratan como plugins, por lo que pueden instalarse y actualizarse por separado de la biblioteca principal
- Para que todas las versiones de la biblioteca puedan leer todos los archivos, la implementación del decodificador se embebe dentro del archivo como binario WebAssembly (Wasm)
- Es decir, cada archivo F3 incluye tanto los datos como el código necesario para leerlos
- La API de F3 no requiere implementaciones separadas para código nativo y para la versión Wasm; el mismo código se compila para ambos destinos sin cambios
- Este diseño hace que F3 esté preparado para el futuro, evita los problemas descritos antes y permite una evolución más rápida que las soluciones existentes
- Los desarrolladores pueden desplegar métodos de codificación futuros en sistemas de producción incluyendo código Wasm dentro del archivo, sin preocuparse por actualizar la versión de la biblioteca en toda la flota
- La sobrecarga de almacenamiento del binario Wasm es mínima (a nivel de kilobytes), y la pérdida de rendimiento de la decodificación Wasm frente a la implementación nativa es pequeña (10 a 30%)
Conclusión
- F3 es un formato de archivo columnar de próxima generación que logra al mismo tiempo interoperabilidad, extensibilidad y eficiencia
- Su diseño eficiente del layout del archivo resuelve ineficiencias de los formatos existentes
- Con una API de decodificación basada en plugins y embebido de Wasm, ofrece un mecanismo preparado para el futuro que permite leer cualquier archivo sin importar la versión de la biblioteca
- La evaluación del prototipo demostró la eficiencia del diseño del layout y la viabilidad práctica del mecanismo Wasm
- La sobrecarga de Wasm, de nivel kilobytes en almacenamiento y de 10 a 30% en rendimiento, se mantiene dentro de un rango aceptable
1 comentarios
Opiniones de Hacker News
Tras revisarlo rápido, parece que corrige muchas de las desventajas de Parquet, así que genera bastante expectativa
Aunque los metadatos de Parquet están basados en Thrift, solo tienen anotaciones del tipo "si este campo existe, entonces aquel campo también debe existir", pero no hay lógica de validación real, así que pienso que si metes un Thrift incorrecto, el lector se puede romper
Como los metadatos de Parquet deben parsearse, se repiten las asignaciones de buffer y las asignaciones dinámicas para parsear metadatos, lo que genera demasiadas asignaciones en el heap. Este formato, al adoptar el enfoque de Flatbuffers, puede interpretar directamente los bytes de Flatbuffer, así que ese problema se resuelve
Siento que la codificación es mucho más potente. Parece que ahora son posibles esas codificaciones ligeras y combinables que la industria de bases de datos ha promovido desde hace mucho tiempo. Formatos previos como BtrBlocks y FastLanes eran superiores a Parquet, y me alegra que aquí se hereden sus buenas ideas
El record-shredding de Dremel en Parquet era demasiado complejo y no me gustaba, así que da gusto que haya desaparecido aquí
En Parquet, como el número de filas dentro de cada DataPage varía, para encontrar una fila deseada hay que escanear todo el ColumnChunk, pero en este formato se puede saltar directamente al DataPage (IOUnit) deseado
Quitaron la compresión pesada y dejaron solo Delta/Dictionary/RLE. La compresión pesada no da beneficios reales, complica la implementación y además trae muchas dependencias externas
En general, es un avance enorme. Ojalá este formato termine dominando la industria del análisis de datos
Si la compresión pesada se refiere a zstd o brotli, entonces es muy útil en columnas de strings con poca repetición
Si metes un compilador de wasm, podrías terminar con más dependencias que con una compresión ‘heavy’
Discusión en StackOverflow sobre agregar columnas a archivos Parquet
¿Parece que hoy en día el método de compresión ya se asentó en zstd?
Parquet es sorprendentemente complejo. Para usarlo bien y de forma eficiente, hay que conocer muchos detalles incómodos y mal documentados, así que no es nada fácil
Wes McKinney
Para quienes no conozcan a Wes McKinney, él es el creador de Pandas, la biblioteca de análisis tabular más usada en Python
Un formato creado por él puede ganarse la confianza del mercado desde una etapa temprana, y como lleva mucho tiempo abordando este problema con verdadero interés, sus ideas se consideran especialmente importantes
Andy Pavlo también merece mención
Como fan, coincido con el enorme impacto de Pandas, pero técnicamente creo que el formato de datos Arrow ha tenido una influencia aún mayor en todo el ecosistema de datos (por ejemplo, DataFusion)
Wes McKinney también es el creador de Apache Arrow
Creo que su trabajo en Parquet me da todavía más confianza
Mezclar datos y código es un error de seguridad clásico
No parece que esto vaya a aplicarse al futuro de los físicos
Los datos a escala de exabytes que se producirán durante los próximos 20 años en el Large Hadron Collider de CERN usan un formato desarrollado internamente por CERN
Material sobre el formato de datos de CERN
CERN lleva tratando con grandes volúmenes de datos desde mucho antes que la mayoría en este campo
Quisiera pedir paciencia porque no termino de entender bien la diferencia con el almacenamiento columnar
Tengo curiosidad por saber por qué esto sería innovador, y me pregunto si la clave es algo como "transportar una pequeña base de datos vectorial de embeddings junto con un sandbox"
El paper me dio la sensación de que podría ser una nueva base, y hasta el nombre del proyecto me transmitió cierta aura francesa (?)
La verdad no entendí la mayor parte del contenido, pero las figuras y la paleta de colores me parecieron bonitas y atrevidas. Desde mi facilidad para dejarme convencer, le doy dos pulgares arriba
La clave es la capa de compatibilidad
La verdadera ventaja del almacenamiento columnar es que permite descomponer esquemas anidados complejos en valores primitivos para almacenarlos
El beneficio real del almacenamiento orientado a columnas es que puedes escanear una columna completa de una sola vez y muy rápido
select a where b = 'x'puede volverse muy rápidaMe decepciona bastante que el decodificador wasm sea 10-30% más lento que el nativo
En la práctica, eso significa aceptar desde el inicio una pérdida de rendimiento de 10-30%, y además renunciar para siempre a futuras oportunidades de mejorar el decodificador
Tampoco se podrán usar funciones avanzadas de decodificación fuera de "decodificar el bloque completo y guardarlo en memoria"
De verdad no entiendo por qué querrían hacerlo así
Si la velocidad importa, wasm no es la respuesta, y si la velocidad no importa tanto, entonces sería mejor usar una codificación ya conocida
WASM se ofrece como respaldo
Coincido en parte, pero el asunto es más complicado
No me queda clara la relación entre Vortex y F3
Ambos hablan de una visión en la que se pueden agregar fácilmente nuevos métodos de codificación sin tener que crear un formato nuevo
En la introducción dicen que usan la implementación de codificaciones de Vortex, pero también aclaran que el sistema de tipos es distinto
El trasfondo del proyecto es complicado
Ahora hasta dan ganas de esperar el anuncio de F4 el próximo año
Me costó bastante encontrar el código fuente, pero está publicado aquí
Como para leer los datos surge la obligación de ejecutar webassembly, no creo que encaje en entornos donde se busca reducir dependencias o bloat
wasm es simple
Si existe un decodificador nativo, no hay necesidad de usar WASM
Parece ser uno de los primeros formatos de archivo en incrustar módulos de WebAssembly
Me interesa especialmente por el lado de la compresión. Pienso que si se diseña bien un preprocesador WASM, se puede mejorar mucho la tasa de compresión
Yo mismo también estoy creando un formato de archivo con ese concepto
Alan Kay alguna vez describió un sistema de almacenamiento en cinta, supuestamente creado por un programador en los años 60, como "el primer sistema orientado a objetos"