Справочник ключевых терминов курса Modern storage formats.
Колоночный файловый формат хранения, де-факто стандарт для аналитических рабочих нагрузок в data lake. Организует данные в Row Group → Column Chunk → Page иерархию. Поддерживает предикатную фильтрацию через min/max статистику, Bloom-фильтры и эффективные кодировки (PLAIN, DICTIONARY, DELTA_BINARY_PACKED).
import pyarrow.parquet as pq
# Чтение с предикатной фильтрацией
table = pq.read_table(
'data.parquet',
filters=[('year', '>=', 2024)]
)
# Запись с настройкой Row Group
pq.write_table(
table, 'output.parquet',
row_group_size=1_000_000
)Горизонтальная партиция данных в Parquet-файле — набор строк, хранящихся вместе. Каждый Row Group содержит Column Chunk для каждой колонки. Типичный размер — 128 MB (по умолчанию в Spark). Row Group определяет единицу параллельного чтения и уровень предикатной фильтрации.
Фрагмент данных одной колонки внутри Row Group. Column Chunk состоит из одной или нескольких Pages и хранит статистику (min, max, null_count) для предикатной фильтрации. Каждый Column Chunk кодируется независимо — можно использовать оптимальную кодировку для каждой колонки.
Минимальная единица ввода-вывода в Parquet. Data Page содержит закодированные и сжатые значения одной колонки. Dictionary Page хранит словарь для DICTIONARY-кодировки. Размер страницы (по умолчанию 1 MB) влияет на гранулярность чтения и эффективность column index.
Колоночный файловый формат, созданный в экосистеме Hadoop/Hive. Организует данные в Stripes (аналог Row Groups). Поддерживает ACID-транзакции через Hive, встроенные индексы (Row Index, Bloom Filter Index) и лёгковесную компрессию (ZLIB, Snappy, LZO, ZSTD).
-- Создание ORC таблицы в Hive
CREATE TABLE events (
event_id BIGINT,
event_type STRING,
timestamp TIMESTAMP
) STORED AS ORC
TBLPROPERTIES (
'orc.compress'='ZSTD',
'orc.stripe.size'='67108864'
);Горизонтальная партиция данных в ORC-файле, аналог Row Group в Parquet. Каждый Stripe содержит Stream-ы для каждой колонки и собственный индекс. Типичный размер — 64 MB. Stripe включает Stripe Footer с метаданными для эффективного пропуска при чтении.
Строковый формат сериализации с встроенной схемой. Данные хранятся в Object Container File, разделённом на блоки с sync markers. Ключевое преимущество — Schema Resolution: читатель может использовать схему, отличную от схемы записи, что обеспечивает эволюцию схемы без перезаписи данных.
from avro.datafile import DataFileReader, DataFileWriter
from avro.io import DatumReader, DatumWriter
import avro.schema
schema = avro.schema.parse(open('user.avsc').read())
writer = DataFileWriter(
open('users.avro', 'wb'),
DatumWriter(), schema
)
writer.append({'name': 'Alice', 'age': 30})
writer.close()Метод представления вложенных структур (nested data) в колоночном формате, разработанный в Google Dremel. Использует Repetition Level и Definition Level для кодирования иерархии без потери структуры. Применяется в Parquet для хранения вложенных полей (list, map, struct).
Бинарный формат сериализации от Google для межсервисного обмена данными. Использует .proto-файлы для описания схемы и генерации кода. Wire format основан на tag-length-value кодировании с varint для целых чисел. Поддерживает прямую и обратную совместимость через номера полей.
// user.proto
syntax = "proto3";
message User {
int64 id = 1;
string name = 2;
repeated string tags = 3;
}Фреймворк сериализации и RPC от Facebook (Meta). Поддерживает несколько протоколов сериализации: BinaryProtocol, CompactProtocol, JSONProtocol. CompactProtocol использует ZigZag и varint кодирование, аналогично Protobuf. Широко используется в Hive, Impala и внутренних сервисах Meta.
Компактный бинарный формат сериализации, совместимый по типам с JSON, но значительно меньше по размеру. Не требует схемы — self-describing формат. Используется в Redis, Fluentd, msgpack-rpc. Занимает нишу между JSON (читаемость) и Protobuf (производительность).
Кодировка целых чисел переменной длины: маленькие значения занимают 1 байт, большие — до 10. Используется в Protobuf, Thrift CompactProtocol и ORC. Каждый байт использует 7 бит для данных и 1 бит-маркер продолжения (MSB). Экономит место при хранении данных с преобладанием малых значений.
Процесс сопоставления схемы записи (writer schema) и схемы чтения (reader schema) в Avro. Позволяет читать данные, записанные с другой версией схемы: добавленные поля получают значения по умолчанию, удалённые поля игнорируются. Основа эволюции схемы без перезаписи данных.
Текстовый формат хранения табличных данных, где значения разделены запятыми (или другим разделителем). Не имеет встроенной схемы, типов данных или сжатия. Несмотря на ограничения (RFC 4180 не покрывает все edge cases), остаётся универсальным форматом обмена данными.
Стандартизированный формат хранения колоночных данных в оперативной памяти. Каждый столбец хранится как набор буферов: validity buffer (битовая маска NULL), offset buffer (для строк и списков) и data buffer. Фиксированное расположение позволяет zero-copy обмен между процессами и языками.
Формат передачи Arrow-данных между процессами. Streaming IPC — последовательные Schema + RecordBatch сообщения, File IPC (Feather v2) — произвольный доступ с footer. Данные передаются без сериализации/десериализации (zero-copy), если выравнивание совпадает.
Файловый формат для быстрого обмена DataFrame между Python (pandas/polars) и R. Feather v2 — это Arrow IPC File Format с опциональным LZ4/ZSTD сжатием. Оптимизирован для максимальной скорости чтения/записи, а не для долговременного хранения.
Высокопроизводительный RPC-протокол поверх gRPC для потоковой передачи Arrow-данных по сети. Flight передаёт RecordBatch в формате Arrow IPC без десериализации на промежуточных узлах. Поддерживает параллельные потоки через FlightEndpoint и авторизацию через middleware.
Техника доступа к данным без копирования из одного буфера в другой. Arrow обеспечивает zero-copy через стандартизированный memory layout: процесс-получатель работает напрямую с буферами отправителя. Требует одинакового выравнивания (8-byte alignment) и порядка байт (little-endian).
Единица данных в Arrow — набор столбцов (arrays) одинаковой длины, объединённых общей схемой. RecordBatch — основная единица передачи в IPC и Flight, единица обработки в DataFusion, DuckDB и Polars. Типичный размер — 8K-64K строк.
Кодировка, заменяющая повторяющиеся значения индексами в словаре. Эффективна при низкой кардинальности (< 10K уникальных значений). Используется в Parquet (PLAIN_DICTIONARY), ORC и Arrow. Размер словаря ограничен размером Data Page — при переполнении Parquet переключается на PLAIN.
# Parquet Dictionary Encoding
# Данные: ['RU','US','RU','DE','RU','US']
# Словарь: {0:'RU', 1:'US', 2:'DE'}
# Индексы: [0, 1, 0, 2, 0, 1]
# Экономия: 6 строк → 3 записи + 6 индексовКодировка, заменяющая последовательности одинаковых значений парой (значение, длина серии). В Parquet используется гибрид RLE/Bit-Packing для Repetition/Definition Levels и словарных индексов. Эффективна для отсортированных данных и колонок с длинными сериями.
Кодировка, хранящая разности между последовательными значениями вместо абсолютных. Идеальна для монотонно растущих данных (timestamps, auto-increment ID). В Parquet реализована как DELTA_BINARY_PACKED (целые) и DELTA_LENGTH_BYTE_ARRAY (строки переменной длины).
Система кодирования из TU Munich, автоматически выбирающая оптимальную схему кодирования для каждого блока данных. Использует sampling и cost model для выбора из пула кодировок (RLE, Dictionary, FOR, Bit-Packing, Pseudodecimal). Показывает 2-4x лучшее сжатие по сравнению с Parquet при сопоставимой скорости декодирования.
Фреймворк кодирования из CWI Amsterdam, оптимизирующий Bit-Packing и Delta для SIMD-инструкций. Ключевая идея — унифицированный транспоз, позволяющий обрабатывать 1024 значения за одну SIMD-операцию независимо от ширины бит. Достигает пропускной способности 30-40 GB/s на современных CPU.
Алгоритм сжатия чисел с плавающей запятой из CWI Amsterdam (авторы DuckDB). Использует наблюдение, что реальные float-данные часто имеют короткое десятичное представление. ALP находит множители 10^e и 10^f для приведения float к целым, затем применяет целочисленное сжатие.
Алгоритм сжатия строк из CWI Amsterdam. Строит символьную таблицу из 255 частотных подстрок (1-8 байт) и заменяет вхождения однобайтовыми кодами. Обеспечивает декомпрессию со скоростью >5 GB/s и совместимость с SIMD-фильтрацией без полной декомпрессии.
Кодировка, хранящая каждое значение в минимальном количестве бит. Если максимальное значение в колонке — 15, достаточно 4 бит вместо 32. В Parquet используется совместно с RLE (гибридная RLE/Bit-Packing кодировка). FastLanes оптимизирует Bit-Packing для SIMD-обработки.
Способность формата или системы обрабатывать данные, записанные с предыдущими версиями схемы, без перезаписи. Включает добавление/удаление колонок, переименование, изменение типов. Разные форматы поддерживают разные уровни: Avro — через Schema Resolution, Parquet — через merge схем, Iceberg — через Column ID.
Свойство схемы: новый читатель может прочитать данные, записанные старым писателем. В Avro достигается через default-значения для новых полей. В Confluent Schema Registry это проверяется автоматически при регистрации новой версии схемы.
Централизованный сервис для хранения, версионирования и валидации схем данных. Confluent Schema Registry — стандарт для Kafka: producer и consumer регистрируют/получают схемы по ID. Обеспечивает контроль совместимости при эволюции. Альтернативы: AWS Glue Schema Registry, Apicurio.
Свойство схемы: старый читатель может прочитать данные, записанные новым писателем. Достигается, когда новая версия только удаляет опциональные поля или добавляет поля с default-значениями в старой схеме. Требуется при rolling updates, когда старые consumer-ы работают одновременно с новыми producer-ами.
Комбинация прямой и обратной совместимости: и старые, и новые читатели могут обрабатывать и старые, и новые данные. Самый строгий уровень, гарантирующий безопасные rolling updates в обоих направлениях. В Confluent Schema Registry задаётся как FULL или FULL_TRANSITIVE.
Уникальный числовой идентификатор колонки в Apache Iceberg. В отличие от Parquet (привязка по имени) или Avro (привязка по позиции), Iceberg использует Column ID для отслеживания колонок при переименовании и реорганизации. Это обеспечивает безопасное переименование без перезаписи данных.
Журнал транзакций Delta Lake — директория _delta_log/ с JSON-файлами (.json) и контрольными точками (.checkpoint.parquet). Каждый коммит создаёт новый JSON-файл с actions (add, remove, metadata, protocol). Delta Log обеспечивает ACID-транзакции, time travel и конкурентный доступ.
Контрольная точка Delta Lake — Parquet-файл со снимком состояния таблицы на определённую версию. Создаётся каждые 10 коммитов (по умолчанию). При чтении таблицы Delta читает последний checkpoint и применяет более поздние JSON-коммиты, что ускоряет start-up при большом числе коммитов.
Метод кластеризации данных в файлах Delta Lake по нескольким колонкам одновременно. Использует Z-кривую (кривую Мортона) для интерливинга битов нескольких колонок, обеспечивая co-locality по всем измерениям. Значительно ускоряет запросы с фильтрами по нескольким колонкам — data skipping пропускает больше файлов.
-- Delta Lake Z-Ordering
OPTIMIZE events ZORDER BY (country, event_type);
-- delta-rs (Python)
dt = DeltaTable('s3://bucket/events')
dt.optimize.z_order(['country', 'event_type'])Механизм Delta Lake для отслеживания изменений (insert, update, delete) между версиями таблицы. При включённом CDF Delta записывает дополнительные файлы _change_data/ с метаданными изменений. Используется для инкрементальной обработки и CDC-пайплайнов.
Библиотека для чтения/записи Delta Lake без привязки к Spark. Delta Kernel предоставляет стандартизированный API для построения коннекторов к Delta-таблицам на любом движке (Flink, Trino, Presto). Устраняет проблему дублирования логики транзакций в каждом коннекторе.
Функция Delta Lake, автоматически генерирующая метаданные Iceberg и Hudi при записи. Позволяет читать Delta-таблицы через Iceberg или Hudi API без конвертации данных. Решает проблему vendor lock-in — данные хранятся как Delta, но доступны через любой табличный формат.
Сервис, хранящий указатель на текущий metadata-файл каждой Iceberg-таблицы. Каталог — единственная точка мутации: атомарный swap указателя обеспечивает ACID. Реализации: Hive Metastore, AWS Glue, Nessie, REST Catalog, JDBC Catalog. Выбор каталога определяет concurrent write guarantees.
Неизменяемый снимок состояния Iceberg-таблицы в определённый момент. Snapshot указывает на manifest list, который перечисляет manifest-файлы с путями к data-файлам. Цепочка snapshot-ов обеспечивает time travel, а snapshot isolation — конкурентное чтение и запись.
Механизм Iceberg, извлекающий partition-значение из данных автоматически через Transform (year, month, day, hour, bucket, truncate). В отличие от Hive-partitioning, пользователь пишет WHERE ts > '2024-01-01', а Iceberg сам определяет, какие партиции пропустить. Partition Evolution позволяет менять схему партиционирования без перезаписи данных.
Avro-файл, перечисляющий набор data-файлов с их partition values, column-level min/max статистикой и статусом (added/deleted). Manifest List указывает на manifest-файлы. Двухуровневая структура (manifest list → manifest → data files) позволяет эффективно пропускать нерелевантные data-файлы при фильтрации.
Механизмы удаления отдельных строк в Iceberg без перезаписи целых файлов. Position Deletes указывают конкретные (file, row_position) пары. Equality Deletes хранят значения ключей удалённых строк. Iceberg v2 поддерживает оба формата; при чтении merge-on-read объединяет data и delete файлы.
Возможность Iceberg менять схему партиционирования таблицы без перезаписи существующих данных. Старые файлы сохраняют прежнюю схему, новые файлы используют новую. Iceberg разрешает запросы, охватывающие обе схемы, через metadata-driven planning. Уникальная возможность, отсутствующая в Hive и Delta Lake.
Упорядоченный журнал всех действий над Hudi-таблицей: коммиты, compaction, cleaning, rollback. Хранится в директории .hoodie/ как файлы с форматом [timestamp].[action].[state]. Timeline обеспечивает конкурентный доступ, time travel и инкрементальные запросы.
Тип таблицы Hudi (и Iceberg), где каждое обновление перезаписывает весь файл, содержащий изменённые строки. CoW обеспечивает быстрое чтение (нет merge overhead), но медленную запись при частых обновлениях. Оптимален для read-heavy workloads с редкими обновлениями.
Тип таблицы Hudi, где обновления записываются в log-файлы (delta), а объединение с base-файлами происходит при чтении или фоновом compaction. MoR обеспечивает быструю запись за счёт замедления чтения. Оптимален для write-heavy и near-real-time сценариев.
Подсистема Hudi для маппинга record key → file group. Определяет, в какой файл попадёт обновление записи. Типы: Bloom Index (bloom filter в каждом файле), Simple Index (brute-force), HBase Index (для глобального индексирования), Bucket Index (hash-based, без lookups).
Apache Paimon использует Log-Structured Merge-Tree как основу хранения, в отличие от файл-ориентированных Delta/Iceberg/Hudi. Данные записываются в уровни LSM-дерева, background compaction объединяет уровни. Это обеспечивает высокую скорость записи потоковых данных и эффективные point lookups.
Механизм Paimon для генерации потока изменений (changelog) при записи или compaction. Режимы: none, input, lookup, full-compaction. Позволяет downstream-системам (Flink) обрабатывать только изменения, а не полный снимок. Аналог Change Data Feed в Delta Lake.
Колоночный формат, оптимизированный для ML и vector search. Ключевая особенность — адресация по fragment + row для быстрого random access к отдельным строкам. Поддерживает версионирование данных, ANN-индексы (IVF-PQ) и append-only запись. Основа LanceDB — embedded vector database.
Формат от Spiral AI, хранящий данные в сжатом виде с возможностью вычислений без декомпрессии (compressed compute). Использует Cascading Encoding — цепочки кодировок, декомпозирующие данные послойно. Поддерживает pushdown операции (filter, take, compare) прямо на сжатых данных.
Формат от Meta, разработанный как эволюция ORC для масштабов data warehouse Meta (эксабайты). Декларативная схема кодирования через EncodingLayout позволяет выбирать оптимальную кодировку для каждого уровня вложенности колонки. Velox-native — интеграция с движком Velox без промежуточных копий.
Формат от Meta с WebAssembly-декодерами: схема кодирования хранится как WASM-модуль внутри файла. Любой читатель с WASM-рантаймом может декодировать данные без знания конкретной кодировки. Это устраняет проблему координации writer-reader при добавлении новых кодировок.
Подход к обработке данных, при котором операции (filter, aggregate, compare) выполняются непосредственно на сжатых данных без полной декомпрессии. Реализован в Vortex через специализированные compute kernels для каждого типа кодировки. Сокращает memory bandwidth и увеличивает эффективный объём L1/L2 cache.
Техника многослойного кодирования в Vortex: данные проходят через цепочку кодировок (Dict → Delta → BitPack), каждая из которых извлекает определённую закономерность. Конечный результат — максимально компактное представление с сохранением возможности pushdown-операций на каждом уровне.
Архитектурный подход, объединяющий гибкость data lake (дешёвое объектное хранилище) с ACID-транзакциями и управлением метаданными data warehouse. Реализуется через табличные форматы (Delta Lake, Iceberg, Hudi) поверх S3/GCS/ADLS. Позволяет использовать один storage layer для ETL, BI, ML и streaming.
Метод организации данных, при котором значения одной колонки хранятся вместе. Преимущества: эффективное сжатие (однородные данные), column pruning (читаются только нужные колонки), SIMD-friendly обработка. Парадигма Parquet, ORC и Arrow. Оптимально для аналитических (OLAP) запросов.
Метод организации данных, при котором все поля одной строки хранятся вместе. Оптимально для OLTP-нагрузок: insert, update, point lookups. Используется в СУБД (PostgreSQL, MySQL) и форматах сериализации (Avro, JSON). Неэффективно для аналитики — приходится читать все колонки даже при запросе одной.
Оптимизация, при которой фильтр (WHERE) применяется на уровне storage engine до загрузки данных в оперативную память. В Parquet: skip Row Group по min/max статистике и Bloom-фильтрам. В Iceberg: skip manifest и data files по partition spec. Критически важна для производительности аналитических запросов.
Техника пропуска файлов или фрагментов данных на основе метаданных, без чтения самих данных. В Parquet — skip Row Groups по column statistics. В Delta Lake — skip файлов по data skipping stats. В Iceberg — skip manifest-файлов по partition summary. Чем лучше кластеризация данных, тем эффективнее data skipping.
Процесс объединения множества мелких файлов в меньшее количество крупных. В Delta Lake — OPTIMIZE команда. В Iceberg — rewrite_data_files(). В Hudi — async compaction для MoR-таблиц. В Paimon — LSM-tree compaction levels. Необходим для борьбы с проблемой мелких файлов (small file problem).
Возможность запрашивать данные на определённую версию или момент времени. В Delta Lake — VERSION AS OF / TIMESTAMP AS OF через Delta Log. В Iceberg — через snapshot-цепочку. В Hudi — через Timeline. Используется для аудита, отладки, воспроизводимости ML-экспериментов.
Систематическое измерение производительности форматов хранения: скорость чтения/записи, коэффициент сжатия, latency запросов, memory footprint. Ключевые методологические требования: изоляция переменных, прогревание кешей, учёт I/O amplification, статистическая значимость. Форматы ведут себя по-разному на разных workloads.