9 pontos por GN⁺ 2025-10-03 | 1 comentários | Compartilhar no WhatsApp
  • F3 (Future-proof File Format) é um formato de armazenamento colunar open source de próxima geração, projetado com interoperabilidade, extensibilidade e eficiência como princípios centrais, eliminando a necessidade de criar um novo formato a cada mudança nos ambientes de processamento e computação de dados
  • Cada arquivo F3 tem uma estrutura autoexplicativa (self-describing), incorporando não apenas dados e metadados, mas também um decodificador binário WebAssembly (Wasm), garantindo compatibilidade em todas as plataformas mesmo sem um decodificador nativo
  • Oferece um layout de armazenamento eficiente, com técnicas modernas de codificação, como compressão em cascata e decodificação vetorizada, além de melhorar problemas de layout do Parquet e do ORC ao separar unidades de I/O, codificação e dicionário
  • Com uma API de decodificação baseada em plugins e um mecanismo de incorporação de Wasm, os desenvolvedores podem adicionar facilmente novos esquemas de codificação, e todos os arquivos podem ser lidos independentemente da versão da biblioteca, resolvendo os problemas de interoperabilidade do Parquet
  • Os resultados da avaliação demonstram a eficiência do layout de armazenamento do F3 e as vantagens da decodificação baseada em Wasm; o overhead de armazenamento é mínimo, na faixa de kilobytes, e a queda de desempenho da decodificação em Wasm em relação ao nativo fica entre 10% e 30%, em um nível aceitável

Contexto e motivação

Limitações dos formatos colunares existentes

  • Parquet e ORC foram desenvolvidos no início dos anos 2010 para sistemas de análise de dados como Hive, Impala e Spark, permitindo o compartilhamento de dados entre data warehouses e data lakes
  • Agora, passados 10 anos, estudos mostram que esses formatos são insuficientes para a análise de dados moderna, porque foram baseados em suposições ultrapassadas sobre desempenho de hardware e padrões de acesso de workload no momento em que foram projetados
    • Nos últimos 10 anos, o desempenho de armazenamento e rede melhorou em dezenas de vezes, mas o desempenho de CPU não acompanhou esse ritmo, fazendo com que os sistemas passem a ter gargalos em computação, e não em I/O
    • Com a ascensão dos data lakes, mais dados passaram a ser armazenados em storages em nuvem de alta largura de banda e alta latência, como o Amazon S3
    • Os aplicativos já não armazenam apenas dados tabulares com poucas colunas. Em workloads de ML, é comum armazenar tabelas largas com milhares de colunas, embeddings vetoriais de alta dimensão e grandes blobs (imagens, vídeos)
    • Também cresceu a demanda por acesso aleatório e atualizações, mas os formatos existentes não são adequados para esses padrões de uso
  • Avanços recentes em compressão, indexação e filtragem tentam resolver essas falhas, mas os formatos de arquivo existentes não foram projetados para serem facilmente extensíveis
    • Mesmo ao adicionar novos recursos, é difícil esperar que as várias implementações em diferentes linguagens das bibliotecas de Parquet e ORC estejam atualizadas
    • Sistemas que usam bibliotecas antigas podem não conseguir decodificar o conteúdo de arquivos novos; por isso, a maioria dos sistemas acaba suportando apenas o menor denominador comum de funcionalidades para evitar problemas de interoperabilidade

Surgimento de novos formatos de arquivo e suas limitações

  • Para superar isso, surgiram propostas de formatos de arquivo totalmente novos, como Meta Nimble, Lance, TSFile, Bullion e BtrBlocks
  • No entanto, eles também cometem os mesmos erros de seus predecessores
    • São projetados com base em suposições sobre hardware e workloads atuais
    • Não promovem extensibilidade fácil para suportar novos recursos sem quebrar a interoperabilidade com implantações existentes
    • Mesmo que um deles substitua Parquet ou ORC como formato dominante, daqui a 10 anos surgirá o mesmo problema: será preciso criar outro formato para corrigir suas falhas

A abordagem do F3

  • O F3 busca atingir simultaneamente interoperabilidade, extensibilidade e eficiência
  • O núcleo do F3 define três especificações principais:
    1. Metadados do conteúdo do arquivo
    2. Layout de agrupamento físico dos dados codificados dentro do arquivo
    3. API de acesso aos dados independente do esquema de codificação usado
  • O esquema de metadados do F3 minimiza os dados necessários para recuperar subconjuntos de colunas de uma tabela
  • O F3 elimina o conceito abrangente de row group do Parquet e resolve problemas de layout ao separar unidades de I/O, codificação e dicionário
  • Integra métodos modernos como compressão em cascata e decodificação vetorizada

Visão geral do F3

Estrutura geral

  • Um arquivo F3 é composto por uma parte de metadados e uma parte de dados
    • Parte de metadados: OptionalData (OptData), Column Metadata (ColMetadata), Footer, Postscript
    • Parte de dados: composta por Row Groups (RG), contendo os dados reais
  • O F3 adota o mesmo layout PAX do Parquet e do ORC
  • Porém, o F3 apresenta várias diferenças centrais em relação aos formatos existentes:
    1. Os metadados eliminam o overhead de desserialização (resolvendo um problema de Parquet/ORC)
    2. A unidade física de I/O (IOUnit) é separada do row group lógico, permitindo ajustar o tamanho da IOUnit de forma independente conforme a mídia de armazenamento
    3. O escopo da codificação por dicionário é separado do row group lógico, permitindo definir, para cada coluna, o alcance mais eficaz
    4. Cada IOUnit é composta por várias Encoding Units (EncUnit), sendo a EncUnit a unidade mínima de codificação e decodificação

Mecanismo de interoperabilidade e extensibilidade

  • O F3 expõe uma API pública que define como uma implementação deve decodificar os dados comprimidos dentro do arquivo
  • Os métodos de codificação são tratados como plugins, podendo ser instalados e atualizados separadamente da biblioteca principal
  • Para que todas as versões da biblioteca consigam ler todos os arquivos, a implementação do decodificador é embutida dentro do arquivo como binário WebAssembly (Wasm)
    • Ou seja, todo arquivo F3 inclui tanto os dados quanto o código necessário para lê-los
  • A API do F3 não exige implementações separadas para código nativo e para a versão Wasm; o mesmo código é compilado para ambos os alvos sem modificações
  • Esse design torna o F3 preparado para o futuro, evita os problemas descritos anteriormente e permite uma evolução mais rápida do que as soluções existentes
    • Desenvolvedores podem distribuir métodos de codificação futuros em sistemas de produção incluindo código Wasm no arquivo, sem se preocupar com upgrades de versão da biblioteca em toda a frota
    • O overhead de armazenamento do binário Wasm é mínimo (na faixa de kilobytes), e a perda de desempenho da decodificação em Wasm em relação à implementação nativa é pequena (10% a 30%)

Conclusão

  • O F3 é um formato de arquivo colunar de próxima geração que alcança ao mesmo tempo interoperabilidade, extensibilidade e eficiência
  • Seu design eficiente de layout de arquivo resolve ineficiências dos formatos existentes
  • Com uma API de decodificação baseada em plugins e incorporação de Wasm, oferece um mecanismo preparado para o futuro, no qual todos os arquivos podem ser lidos independentemente da versão da biblioteca
  • A avaliação do protótipo comprovou a eficiência do design de layout e a viabilidade prática do mecanismo com Wasm
  • O overhead do Wasm permanece em uma faixa aceitável: armazenamento em kilobytes e perda de desempenho de 10% a 30%

1 comentários

 
GN⁺ 2025-10-03
Comentários do Hacker News
  • Pelo que vi rapidamente, parece corrigir muitas das desvantagens do Parquet, então estou bem animado

    • Os metadados do Parquet são baseados em Thrift, mas só têm observações do tipo "se este campo existir, aquele campo também deve existir", sem lógica de validação real, então imagino que um Thrift inválido possa quebrar o leitor

    • Como os metadados do Parquet precisam ser parseados, há alocações de buffer e alocações dinâmicas repetidas para o parsing, gerando heap allocations demais. Este formato novo, ao adotar Flatbuffers, resolve isso porque permite interpretar diretamente os bytes do Flatbuffer

    • A codificação parece muito mais poderosa. Dá a impressão de finalmente permitir codificações leves e combináveis, defendidas há muito tempo no setor de bancos de dados. Formatos existentes como BtrBlocks e FastLanes eram superiores ao Parquet, e é bom ver que as boas ideias deles foram herdadas

    • Eu não gostava da complexidade do record-shredding do Dremel no Parquet, então fico feliz que isso tenha desaparecido aqui

    • No Parquet, como o número de linhas dentro de um DataPage varia, é preciso escanear o ColumnChunk inteiro para achar a linha desejada, mas neste formato dá para pular direto para o DataPage (IOUnit) desejado

    • Removeram a compressão pesada e deixaram só Delta/Dictionary/RLE. Compressão pesada não traz ganho real, é chata de implementar e ainda adiciona muitas dependências externas

    • No geral, é um avanço impressionante. Espero que esse formato domine o setor de análise de dados

    • Se por compressão pesada você quer dizer zstd ou brotli, ela é muito útil em colunas de string com pouca repetição

      • Na prática, a maior parte era ASCII e havia muitos prefixos comuns, então já vi taxa de compressão cair para 1%
    • Se entrar um compilador wasm, isso pode acabar trazendo ainda mais dependências do que uma compressão ‘heavy’

      • Antigamente, recursos de CPU eram relativamente mais abundantes do que largura de banda de rede ou disco, então compressão pesada fazia mais sentido; hoje essa diferença é menor
    • Discussão no StackOverflow sobre adicionar colunas a um arquivo Parquet

    • Hoje em dia o método de compressão não acabou se consolidando em zstd?

    • O Parquet é surpreendentemente complexo. Para usá-lo de forma realmente eficiente, é preciso dominar muitos detalhes incômodos e mal documentados, então não é nada simples

  • Wes McKinney

    • Para quem não conhece Wes McKinney: ele é o criador do Pandas, a biblioteca de análise tabular mais usada em Python

    • Um formato criado por ele tende a ganhar confiança do mercado desde o começo, e como ele aborda esse tipo de problema com dedicação de longo prazo, seus insights têm peso especial

    • Andy Pavlo também merece ser mencionado

      • Ele é especialista em bancos de dados e famoso por viver uma vida centrada em dados
      • As duas versões do artigo dele, "What goes around comes around", ajudam a enxergar com facilidade o passado e o futuro da área de bancos de dados
      • A CMU Seminar Series também é excelente, e o fato de ele participar aumenta ainda mais minha expectativa
      • Não conheço bem os coautores chineses e me sinto até mal por isso, mas pretendo guardar este artigo e lê-lo com atenção
    • Como fã, concordo com a influência do Pandas, mas tecnicamente acho que o formato de dados Arrow teve um impacto ainda maior em todo o ecossistema de dados, como em exemplos tipo DataFusion

      • Agora quero ver o que o F3 realmente é na prática (você me fez clicar no link)
    • Wes McKinney também é o criador do Apache Arrow

      • Um componente central da análise de dados moderna
    • Acho que o trabalho dele com Parquet acaba inspirando ainda mais confiança

    • Misturar dados e código é um erro clássico de segurança

      • A participação de gente famosa não faz esse tipo de erro desaparecer
  • Não acho que isso vá se aplicar ao futuro dos físicos

  • Peço desculpas por não entender bem a diferença em relação ao armazenamento colunar

    • Tenho curiosidade sobre por que isso seria revolucionário; a pergunta seria algo como: "o ponto central é transportar um pequeno banco vetorial de embeddings junto com um sandbox?"

    • O artigo me passou a sensação de uma nova base para o futuro, e até o nome do projeto tem uma aura francesa(?)

    • Eu mesmo não entendi a maior parte do conteúdo; só achei os diagramas e as cores bonitos e ousados. Como alguém fácil de convencer, dou dois joinhas

    • O ponto principal é a camada de compatibilidade

      • Por exemplo, o ORCv2 tentou criar uma nova versão do formato e lançar recursos aos poucos, mas no fim nunca conseguiu ser lançado
      • Se desse para distribuir uma nova codificação de float no arquivo junto com um shim em WASM, seria fácil entregar o novo formato sem atualizar o software leitor nem enfrentar problemas de compatibilidade
      • Quando é necessário fazer recombinações complexas, como no tipo variant do Spark, também fica muito mais simples distribuir isso em bytecode em vez de um interpretador
      • Pessoalmente, tenho orgulho de ver um bench aguentando firme depois de eu passar a noite tunando ORC
    • A verdadeira vantagem do armazenamento colunar é permitir quebrar esquemas aninhados complexos em valores primitivos para armazenamento

      • Isso aumenta muito a eficiência de I/O e de parsing ao ler diretamente os valores leaf
      • Os formatos normalmente são particionados em grupos de linhas no nível mais alto
      • Este formato permite receber buffers do Apache Arrow diretamente da página de dados, seja usando WASM ou um decodificador nativo
      • O Parquet atualmente é muito complexo. Ele usa a codificação Dremel para armazenar valores primitivos junto com dois fluxos de inteiros (repetition/definition level), o que é difícil de parsear para pessoas comuns
      • Em especial porque ele mistura bit-packing com RLE, e só o código de bit-packing na implementação de referência tem 74 mil linhas
      • Converter isso para buffers Arrow exige bastante trabalho. Com o F3, isso seria muito mais fácil e mais compatível com o futuro
      • Além disso, o fato de permitir random access aos metadados também é importante
      • Por exemplo, ao usar GeoParquet, sem criar um índice SQLite, uma única consulta espacial leva em média 10 minutos, e o parsing dos footers de 500 arquivos exige 150 MB de parsing de Thrift
      • A escolha de Flatbuffers é inesperada. Há problemas conhecidos de segurança de memória no Flatbuffers (observação relacionada)
      • Fico pensando se não seria melhor simplesmente colocar um banco SQLite lá dentro
    • O verdadeiro ganho do armazenamento colunar é poder escanear uma coluna inteira de uma vez com muita velocidade

      • Isso permite usar o buffer do sistema operacional com muita eficiência. Por exemplo, uma consulta como select a where b = 'x' fica muito rápida
  • É uma pena ver que o decodificador wasm é 10-30% mais lento que o nativo

    • Isso significa aceitar uma perda de desempenho de 10-30% logo de saída e abrir mão para sempre de oportunidades futuras de melhorar o decodificador

    • Também impede usar recursos avançados de decodificação além de "decodificar o bloco inteiro e gravar em memória"

    • Realmente não entendo por que fariam isso de propósito

    • Se velocidade importa, wasm não é a resposta; se velocidade não importa tanto, então seria melhor usar uma codificação bem conhecida

    • O WASM é fornecido como backup

      • Se um decodificador nativo estiver instalado, como um crate, ele é usado primeiro; se não estiver, faz fallback para WASM
      • A ideia é que aceitar uma perda de 10-30% é melhor do que simplesmente não conseguir ler o arquivo
    • Concordo em parte, mas a questão é mais complicada

      • O mesmo tipo de situação já se repete quando se usam vários métodos de compressão
      • Por exemplo, sempre que muda o método de bitpack ou a compressão, é preciso fazer "transcoding", ou seja, reescrever o arquivo
      • Mesmo com a introdução de WASM, isso continua valendo
      • Fico em dúvida se esse ganho de preparação para o futuro realmente compensa. Em sistemas na escala de exabytes, recodificar dados é realmente muito difícil
  • Não entendo exatamente qual é a relação entre Vortex e F3

    • Ambos falam de uma visão em que dá para adicionar facilmente novos métodos de codificação sem precisar criar um novo formato

    • Na introdução, diz que usam a implementação de codificação do Vortex, mas também que o sistema de tipos é diferente

    • O histórico do projeto é complicado

      • No começo, CMU, Tsinghua, Meta, CWI, VoltronData, Nvidia e SpiralDB formaram um consórcio para unificar um único formato de arquivo
      • Mas isso fracassou por causa de um problema entre os advogados da CMU e o NDA da Meta
      • Então cada um lançou seu próprio formato
      • Em termos de pesquisa, CMU+Tsinghua focou mais em embutir WASM do que em desenvolver codificadores
      • Foi Hannes, do DuckDB, quem sugeriu a ideia pela primeira vez ao Wes McKinney
      • Como a implementação de codificação do Vortex é baseada em Rust, com alguns ajustes a maior parte dela pode ser compilada para WASM
      • Vortex é um projeto independente, separado do F3, e o F3 no momento é um protótipo acadêmico
      • Na Alemanha, também lançaram este ano um formato separado usando WASM: formato AnyBlox (ele transforma o arquivo inteiro em WASM; o F3 faz isso por grupo de colunas)
  • Agora fiquei na expectativa pelo anúncio do F4 no ano que vem

  • Passei um tempão procurando onde estava o código-fonte, mas ele está disponível aqui

  • O fato de ser obrigatório executar webassembly para ler os dados me faz pensar que isso não é adequado para ambientes que querem reduzir dependências ou bloat

    • wasm é simples

      • Não tem relação necessária com "web"
      • Como outra pessoa já disse, wasm é um backup
      • Se houver um binding nativo, o desempenho será melhor
    • Se existir um decodificador nativo, não há necessidade de usar WASM

      • Isso também está claramente dito no resumo
  • Parece ser um dos primeiros formatos de arquivo a embutir módulos WebAssembly

    • Tenho interesse nisso especialmente do ponto de vista de compressão. Se um pré-processador em WASM for bem projetado, a taxa de compressão pode melhorar bastante

    • Eu também estou criando um formato de arquivo com esse conceito

    • Alan Kay certa vez descreveu um sistema de armazenamento em fita, supostamente criado por um programador nos anos 60, como "o primeiro sistema orientado a objetos"

      • O formato da fita incluía um conjunto de rotinas para leitura e escrita em posições específicas
      • Ou seja, há um precedente histórico
      • Link do artigo relacionado (página 4)