F3 — Wasm-декодеры
В предыдущем уроке мы разобрали структуру F3: IOUnits, EncUnits, FlatBuffer metadata. Но главная инновация F3 — embedded WebAssembly decoders. Каждый F3 файл содержит скомпилированный Wasm-код, способный декодировать собственные данные. Это самый радикальный подход к extensibility среди всех форматов в курсе.
Проблема: как обновить кодировки на 10 000 серверов
Представьте: исследователь в CMU разрабатывает новую кодировку для float64, которая сжимает на 30% лучше ALP. Как её внедрить?
Новая кодировка: super-alp-float64
Новая кодировка: super-alp-float64. Сжимает float64 на 30% лучше, чем ALP. Реализация: 500 строк Rust/C++ кода. Хотим использовать в production.Это не гипотетическая проблема. Parquet encoding evolution: DELTA_BINARY_PACKED (2014) → BYTE_STREAM_SPLIT (2020) → DELTA_BYTE_ARRAY improvements (2022). Каждое добавление = multi-year process. Между тем, research на encoding’ах движется быстрее: ALP (2023), FastLanes (2023), FSST (2020), BtrBlocks (2023) — все появились быстрее, чем Parquet может их adopt.
Как работает Wasm в F3
WebAssembly (Wasm) — компактный бинарный формат для portable выполнения кода. Разработан для браузеров, но активно используется server-side (Wasmtime, Wasmer, WasmEdge):
Writer: Rust encoding → Compile to Wasm
Writer: реализует encoding на Rust/C/C++. Компилирует в Wasm target (wasm32-wasi или wasm32-unknown-unknown). Размер: исходный Rust код ~500 строк → Wasm binary ~5-50KB (tiny по сравнению с данными файла).Self-Describing F3 File
File на storage: содержит данные (EncUnits с encoded payloads) + metadata (FlatBuffers) + Wasm decoders (в footer). Файл полностью самодостаточен — любой reader с Wasm runtime может его прочитать.Decoded Column Data
Decoded data: стандартный columnar output. Reader не знал encoding заранее — Wasm decoder «научил» его декодировать. Любой future encoding: тот же pipeline.Performance: Wasm overhead
Ключевой вопрос: какова цена universality? F3 SIGMOD paper измеряет overhead:
Wasm module size: 2-50KB. Для context: один Parquet data page = ~64KB. Overhead embedding Wasm decoders в файл = negligible. Файл 1GB с 5 encodings: 100KB Wasm / 1GB data = 0.01% overhead.
Sandbox Security
Wasm execution в sandbox — важное свойство. Reader выполняет чужой код (decoder из файла), но Wasm гарантирует изоляцию:
Native Plugin (C/C++ .so)
Native plugin model (C/C++ shared library): полный доступ к памяти процесса, файловой системе, сети. Malicious decoder может: прочитать secrets, модифицировать данные, exfiltrate data. Unsafe.Wasm Decoder (sandboxed)
Wasm sandbox (Wasmtime): decoder работает в изолированном linear memory. Нет доступа к host memory, файловой системе, сети. Может только: читать input buffer, писать output buffer. Вызвать decode() — и всё.Sandbox не защищает от всего. Wasm decoder может: (1) consume excessive CPU (infinite loop — нужен timeout), (2) allocate excessive memory (нужен memory limit в Wasmtime config), (3) return incorrect results (нет way to verify correctness без known-good decoder). F3 — research prototype, production security model требует дополнительных гарантий.
Три подхода к расширяемости
F3 представляет один из трёх подходов к решению проблемы encoding extensibility. Сравним:
Nimble: One Library
Nimble: одна библиотека. Добавить кодировку = PR в один репозиторий. Нет coordination overhead. Но: reader ДОЛЖЕН быть обновлён. Если reader старый — не читает новую кодировку.Vortex: Pluggable Encodings
Vortex: pluggable encodings через Rust traits. Третьи стороны могут реализовать trait → register encoding → Vortex reader вызывает через vtable dispatch. Self-describing layouts для forward compat.F3: Embedded Wasm
F3: embedded Wasm decoders. Каждый файл содержит decoder'ы. Reader с Wasmtime runtime декодирует любой файл. Нет зависимости от конкретной библиотеки. Максимальная portability.Deployment Model Comparison
Визуализация процесса deploy новой кодировки в трёх моделях:
Encoding Lifecycle в F3
Как новая кодировка проходит полный lifecycle от разработки до использования:
- Research: новый encoding
- Compile: Rust → Wasm
- Writer: embed decoder
- File → data lake
- Reader: load Wasm → decode
- Optional: add native decoder
Phase 6 — опциональная оптимизация: если encoding стал популярным, reader library может добавить native decoder. Тогда: known encoding → native decode (100% speed), unknown → Wasm decode (70-90% speed). Gradual optimization без breaking change.
Wasm vs Native: детальное сравнение
10-30% overhead — результат из SIGMOD 2025 paper. Для context: разница между ZSTD level 1 и level 3 compression = ~30% decode speed. Wasm overhead сопоставим с выбором compression level — не catastrophic, но заметен для hot decode paths.
Спектр расширяемости: от Parquet до F3
Все форматы курса можно расположить на спектре «extensibility vs performance vs ecosystem»:
Практические импликации
Хотя F3 — research prototype, идеи embedded decoders уже влияют на production форматы:
Итоги
Embedded Wasm decoders — самый амбициозный подход к extensibility среди форматов нового поколения:
-
Мгновенный deploy. Новая кодировка = compile to Wasm → embed в файлы. Нет fleet upgrades, нет coordination. Writer-driven evolution.
-
Universal portability. Любой reader с Wasm runtime (Wasmtime, Wasmer, WasmEdge, browser) декодирует любой F3 файл. Нет language lock-in.
-
Sandbox security. Wasm decoders работают в изолированной памяти. Нет доступа к host, файловой системе, сети. Safe execution of untrusted code.
-
Acceptable overhead. 10-30% vs native — сопоставимо с выбором compression level. Storage layout improvements offset часть overhead.
-
Research prototype. F3 — proof of concept, не production format. Но идеи уже влияют на Vortex (Wasm fallback) и discussions о Parquet 3.0.
В следующем уроке — сравнение всех форматов нового поколения: Lance vs Vortex vs Nimble vs F3 vs Parquet. Какой формат для какого use case, и ответ на вопрос «заменят ли они Parquet?».