9 puntos por GN⁺ 2025-10-03 | 1 comentarios | Compartir por WhatsApp
  • 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:
    1. Los metadatos del contenido del archivo
    2. El layout de agrupamiento físico de los datos codificados dentro del archivo
    3. 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:
    1. Los metadatos eliminan la sobrecarga de deserialización (resolviendo un problema de Parquet/ORC)
    2. 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
    3. 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
    4. 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

 
GN⁺ 2025-10-03
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

      • De hecho, he visto casos con strings mayormente ASCII y muchas subcadenas en común donde la compresión llegó hasta 1%
    • Si metes un compilador de wasm, podrías terminar con más dependencias que con una compresión ‘heavy’

      • Antes, cuando los recursos de CPU eran relativamente más abundantes que el ancho de banda de red o disco, la compresión pesada tenía más sentido, pero ahora esa diferencia es menor
    • 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

      • Es un experto en bases de datos y es famoso por vivir una vida centrada en los datos
      • Si revisas sus dos papers "What goes around comes around", puedes tener una visión clara del pasado y futuro del campo de las bases de datos
      • La CMU Seminar Series también es excelente, y que él participe genera aún más expectativas
      • No conozco bien a los coautores chinos, y me da pena decirlo, pero voy a guardar este paper y leerlo con atenció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)

      • Ahora quiero ver qué es exactamente F3 (gracias a ti terminé haciendo clic en el enlace)
    • Wes McKinney también es el creador de Apache Arrow

      • Es un componente central del análisis de datos moderno
    • 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

      • Que participe una celebridad no hace que los errores desaparezcan
  • No parece que esto vaya a aplicarse al futuro de los físicos

  • 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

      • Por ejemplo, ORCv2 intentó crear una nueva versión del formato y desplegar funciones gradualmente, pero al final nunca logró salir
      • Si hubieran podido distribuir una nueva codificación de float dentro del archivo junto con un shim de WASM, habrían podido entregar fácilmente el nuevo formato sin actualizar el software lector ni chocar con problemas de compatibilidad
      • Incluso cuando se necesita una recombinación compleja como el tipo variant de Spark, sería mucho más fácil distribuirlo como bytecode en lugar de un intérprete
      • Personalmente, recuerdo haber pasado noches enteras afinando ORC y sentir orgullo cuando aguantaba bien en el bench
    • La verdadera ventaja del almacenamiento columnar es que permite descomponer esquemas anidados complejos en valores primitivos para almacenarlos

      • Leer directamente los valores leaf mejora muchísimo la eficiencia de I/O y del parseo
      • Los formatos suelen particionarse a nivel superior en grupos de filas
      • Este formato permite recibir buffers de Apache Arrow directamente desde la página de datos, ya sea usando WASM o un decodificador nativo
      • Parquet hoy es extremadamente complejo. Usa la codificación Dremel para guardar valores primitivos junto con dos streams de enteros (repetition/definition level), lo que hace muy difícil su parseo para la gente común
      • Sobre todo porque mezcla bit-packing + RLE, y solo el código de bit-packing en la implementación de referencia tiene 74 mil líneas
      • Convertir eso a buffers de Arrow requiere bastante trabajo. Con F3 sería mucho más fácil y además tendría mejor compatibilidad futura
      • También es muy importante que se vuelva posible el acceso aleatorio a metadatos
      • Por ejemplo, al usar GeoParquet, si no pones un índice de SQLite, una sola consulta espacial tarda en promedio 10 minutos, y parsear los footers de 500 archivos requiere 150 MB de parseo Thrift
      • La elección de Flatbuffers es inesperada. Sus problemas de seguridad de memoria son conocidos (señalamiento relacionado)
      • Incluso pienso que quizá sería mejor meter una base de datos SQLite
    • El beneficio real del almacenamiento orientado a columnas es que puedes escanear una columna completa de una sola vez y muy rápido

      • Eso permite usar de forma muy eficiente los buffers del sistema operativo. Por ejemplo, una consulta como select a where b = 'x' puede volverse muy rápida
  • Me 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

      • Si está instalado un decodificador nativo (por ejemplo, un crate), se usa primero ese; si no, se hace fallback a WASM
      • La idea es que asumir una pérdida de 10-30% es mejor que no poder leer el archivo en absoluto
    • Coincido en parte, pero el asunto es más complicado

      • Algo parecido ya se repite al usar distintos métodos de compresión
      • Por ejemplo, cada vez que cambias el método de bitpack o de compresión, necesitas "transcodificación", es decir, reescribir el archivo
      • Incluso después de introducir WASM, sigue siendo necesario reescribir archivos
      • Queda la duda de si ese enfoque orientado al futuro realmente vale la pena. En sistemas a escala de exabytes, recodificar datos es realmente durísimo
  • 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

      • Al principio, CMU, Tsinghua, Meta, CWI, VoltronData, Nvidia y SpiralDB formaron un consorcio para intentar unificar un solo formato de archivo
      • Pero eso se cayó por un tema del abogado de CMU relacionado con el NDA (acuerdo de confidencialidad) de Meta
      • Así que cada quien terminó lanzando su propio formato de archivo
      • En términos de investigación, CMU+Tsinghua se enfocó en incrustar WASM más que en desarrollar codificadores
      • Hannes de DuckDB fue quien primero le propuso la idea a Wes McKinney
      • Como la implementación de codificaciones de Vortex está basada en Rust, con algunos ajustes casi toda puede compilarse a WASM
      • Vortex es un proyecto independiente y separado de F3, y F3 por ahora es un prototipo académico
      • En Alemania también lanzaron este año otro formato que usa WASM por separado: formato AnyBlox (convierte todo el archivo en WASM; F3 lo hace por grupo de columnas)
  • 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

      • No tiene que ver con la "web"
      • Como ya dijo otra persona, wasm es un respaldo
      • Si se ofrecen bindings nativos, el rendimiento mejora más
    • Si existe un decodificador nativo, no hay necesidad de usar WASM

      • Eso también aparece claramente en el resumen
  • 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"

      • El formato de la cinta incluía un conjunto de rutinas para leer y escribir en posiciones específicas
      • O sea, sí existe un antecedente de referencia
      • Enlace al paper relacionado (página 4)