Learning Platform
Глоссарий Troubleshooting
Урок 04.06 · 30 мин
Продвинутый
ORCColumn EncryptionSchema EvolutionCompressionAESKMSORC vs Parquet

Шифрование, Schema Evolution, сравнение с Parquet

Column Encryption

Начиная с Apache ORC 1.6, формат поддерживает column-level encryption — шифрование отдельных колонок без шифрования всего файла. Это позволяет разным пользователям видеть разные колонки в зависимости от их ключей доступа.

Архитектура Column Encryption в ORC

KMS (Key Management Service)

Key Management Service (KMS) — внешний сервис, хранящий master keys. ORC writer запрашивает у KMS ключи шифрования перед записью. Hadoop KMS, AWS KMS, Azure Key Vault.
Генерация DEK (Data Encryption Key)Writer получает от KMS master key и генерирует data encryption key (DEK) для каждой encryption zone. DEK шифрует данные, encrypted DEK хранится в Footer.
Encryption Zone AГруппа колонок, зашифрованных одним ключом. Например: PII данные (name, email, phone). Один DEK на всю зону.
Encryption Zone BДругая группа колонок с другим ключом. Например: финансовые данные. Разные зоны — разные DEK — разные права доступа.
UnencryptedКолонки без шифрования. Читаются всеми пользователями без ключей. Например: timestamps, public IDs.

Алгоритм шифрования

ORC использует AES/CTR (Counter Mode) для шифрования данных:

AES/CTR в ORC

Что шифруется

Data StreamsDATA, LENGTH, DICTIONARY_DATA, SECONDARY — все потоки данных зашифрованной колонки. Шифрование применяется ПОСЛЕ компрессии (compress-then-encrypt).
Index StreamsROW_INDEX и BLOOM_FILTER streams тоже шифруются. Без ключа нельзя даже выполнить predicate pushdown по зашифрованной колонке.
Column StatisticsMin/max/count/sum статистики зашифрованных колонок — тоже зашифрованы. Без ключа видны только агрегаты незашифрованных колонок.

Что НЕ шифруется

PostScriptPostScript всегда открыт — иначе невозможно начать парсинг файла (chicken-and-egg). Содержит magic, version, compression, lengths.
Stripe FooterStream directory — перечень streams с их sizes и offsets. Нужен для навигации. Тип и размер stream видны, содержимое — нет.
Type Tree (schema)Имена и типы колонок видны всем. Шифруется содержимое, не структура. Это design choice — позволяет schema-aware инструментам работать без ключей.
NOTE

Порядок операций: compress → encrypt. Данные сначала сжимаются (ZSTD, ZLIB, etc.), затем шифрованный блок записывается в файл. При чтении — обратный порядок: decrypt → decompress. AES/CTR поддерживает два размера ключа: 128-bit и 256-bit.

Masked Data

Без доступа к ключу ридер видит зашифрованные колонки как masked data — специальные значения вместо реальных:

Тип данныхMasked значениеПоведение
STRINGnull или redactedРидер возвращает null
INT/BIGINTnullЧисловые колонки — null
StatisticsЗашифрованыMin/max/count недоступны
Bloom filtersЗашифрованыPredicate pushdown невозможен

Schema Evolution

ORC поддерживает ограниченную schema evolution — изменение схемы без перезаписи данных:

Поддерживаемые операции Schema Evolution
Да Добавление колонокНовые колонки добавляются в конец type tree. Старые файлы возвращают NULL для новых колонок. Наиболее частая и безопасная операция.
Да Расширение числового типаINT → BIGINT, FLOAT → DOUBLE. Данные конвертируются при чтении без потерь. Только расширение — сужение (BIGINT → INT) не поддерживается.
Да Переименование колонокПо умолчанию ORC использует positional matching (по column ID в type tree). Переименование колонки не ломает чтение — ID остаётся тем же. Но при name-based matching — ломает.
Нет Удаление колонокORC не поддерживает удаление колонок из schema. Можно перестать записывать колонку в новые файлы, но старые файлы по-прежнему содержат её данные. Требуется перезапись.
Нет Изменение типа (несовместимое)STRING → INT, BIGINT → INT, TIMESTAMP → DATE — не поддерживаются. Narrowing conversions вызывают ошибку при чтении.
Нет Переупорядочивание колонокPositional matching привязывает column ID к позиции в type tree. Изменение порядка нарушает mapping. При name-based matching — допустимо.
WARNING

ORC имеет два режима schema matching: positional (по умолчанию) и name-based (orc.force.positional.evolution=false). Positional безопаснее для добавления колонок в конец, но не поддерживает переупорядочивание. Name-based гибче, но уязвим к переименованиям. Выбор режима — одноразовое архитектурное решение.

Архитектура компрессии

ORC сжимает данные на уровне chunks (блоков) внутри streams. Каждый блок имеет 3-байтовый заголовок:

Компрессия на уровне chunks
ORC Stream (один поток данных)Один stream (DATA, LENGTH, etc.) разбивается на chunks размером compressionBlockSize (default 256 KB). Каждый chunk сжимается независимо.

Формат 3-байтового заголовка:

byte 0: [is_original:1][length_low:7]
byte 1: [length_mid:8]
byte 2: [length_high:8]

is_original = 0 → данные сжаты кодеком из PostScript
is_original = 1 → данные не сжаты (компрессия неэффективна)
length = (byte2 << 15) | (byte1 << 7) | (byte0 >> 1)
КодекОписаниеТипичное применение
NONEБез компрессииУже сжатые данные, тесты
ZLIBDeflate (gzip-совместим)Универсальный, хороший ratio
SNAPPYLZ77-based, быстрыйСкорость > ratio
LZOLempel-Ziv-OberhumerLegacy, требует лицензию
LZ4Очень быстрый, moderate ratioReal-time pipelines
ZSTDZstandardЛучший ratio при хорошей скорости
TIP

По умолчанию ORC использует ZLIB (дефолт ORC library) или SNAPPY (дефолт в некоторых Hive конфигурациях). Для новых проектов рекомендуется ZSTD — лучшее соотношение compression ratio / скорость.

ORC vs Parquet: детальное сравнение

ORC vs Parquet — архитектурные решения

ORC

МетаданныеProtocol Buffers — компактная бинарная сериализация. Schema описывается .proto файлом. Быстрый парсинг, меньший overhead.
ИндексыТри уровня индексов: file (Footer stats), stripe (Metadata), row (Row Index per 10K rows). Bloom filters — встроенные (UTF8-вариант).
КодировкиType-specific: RLEv2 (4 подкодировки) для integers, Byte RLE для booleans/bytes, Dictionary с sorted keys для strings. Меньше вариантов, но оптимизированы под каждый тип.
ACIDHive ACID — единственная production-ready реализация ACID на columnar storage. Base + delta, compaction, row ID.

Parquet

МетаданныеApache Thrift — более verbose сериализация. Schema описывается IDL. Широкая поддержка в экосистеме, но больший overhead на парсинг.
ИндексыДва уровня: file (FileMetaData stats), column chunk (page stats с column/offset indexes). Bloom filters — опциональные (добавлены позже). Page-level indexes — с Parquet 2.0.
КодировкиUniversal: PLAIN, RLE_DICTIONARY (любой тип), DELTA_BINARY_PACKED, DELTA_LENGTH_BYTE_ARRAY, BYTE_STREAM_SPLIT. Больше вариантов, writer выбирает оптимальную.
ACIDНет встроенного ACID. Реализуется через внешние table formats: Delta Lake, Apache Iceberg, Apache Hudi. Каждый — отдельный проект.

Сводная таблица

ХарактеристикаORCParquet
ОрганизацияApache (бывш. Hive sub-project)Apache (бывш. Twitter/Cloudera)
Magic numberORC (3 байта)PAR1 (4 байта)
Сериализация метаданныхProtocol BuffersApache Thrift
Horizontal splitStripe (64–250 MB)Row Group (~128 MB)
Компрессия метаданныхFooter сжатFooter не сжат
BootstrapPostScript (не сжат)Footer length (4 bytes LE)
Index stride10 000 строк (default)Per-page (Data Page V2)
Bloom filtersВстроенные (murmur3 + wang)Опциональные (murmur3)
Integer encodingRLEv2 (Short Repeat, Direct, Patched Base, Delta)RLE_DICTIONARY, DELTA_BINARY_PACKED
String encodingDictionary (sorted) + RLEv2RLE_DICTIONARY + PLAIN fallback
Float encodingIEEE 754 прямая записьBYTE_STREAM_SPLIT (split по байтам)
Nested typesSTRUCT, LIST, MAP, UNIONgroup, repeated, map (logical)
Column encryptionAES/CTR, per-column (since ORC 1.6)AES/GCM + AES/CTR (Parquet-MR)
Schema evolutionPositional + name-basedName-based (по умолчанию)
ACID транзакцииHive ACID (native)Delta Lake / Iceberg / Hudi
ЭкосистемаHive, Spark, Presto/Trino, FlinkSpark, DuckDB, Polars, Arrow, Pandas
Python APIpyarrow.orc (базовая)pyarrow.parquet (полная)
NOTE

В реальных проектах выбор между ORC и Parquet часто определяется экосистемой, а не техническими характеристиками формата. Hive-центричные pipeline используют ORC. Spark/Arrow/DuckDB-центричные — Parquet. Оба формата production-ready и решают одну задачу — эффективное колоночное хранение.

Когда выбирать ORC

Дерево решений: ORC или Parquet

Нужен ACID без Delta Lake / Iceberg?

Первый вопрос: нужны ли вам UPDATE/DELETE без внешнего table format (Delta Lake, Iceberg)?

→ ORC (Hive ACID)

Если нужен ACID и используется Hive — ORC единственный вариант. Hive ACID работает ТОЛЬКО с ORC.

→ следующий вопрос

Если ACID не нужен или используете Delta Lake/Iceberg — следующий вопрос.

Основной движок чтения?

Второй вопрос: основной инструмент чтения данных?

Hive / Presto → ORC

Hive, Presto/Trino с Hive connector — ORC оптимизирован для этого стека. Predicate pushdown, bloom filters, vectorized reader.

Spark / DuckDB / Polars → Parquet

Spark, DuckDB, Polars, Pandas, Arrow — Parquet имеет лучшую поддержку. Arrow-native формат, zero-copy читатели, широкая экосистема.

Ключевые выводы

  1. Column encryption: AES/CTR, per-column, управление ключами через KMS. Шифруются данные, индексы и статистики — но не PostScript и schema
  2. Schema evolution: безопасно добавлять колонки в конец и расширять числовые типы. Удаление и переупорядочивание — не поддерживаются
  3. Компрессия: chunk-level с 3-байтовым заголовком, is_original флаг для несжимаемых блоков. Рекомендуется ZSTD
  4. ORC vs Parquet: похожие по архитектуре, отличаются экосистемой. ORC — Hive/ACID, Parquet — Arrow/Spark/DuckDB
  5. Выбор формата определяется инструментами и потребностью в ACID, а не техническим превосходством одного над другим

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. ORC column encryption: зашифрованы колонки salary и ssn. Аналитик без ключа шифрования выполняет SELECT department, COUNT(*) GROUP BY department. Что произойдёт?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7