Основы компрессии
Компрессия — финальная стадия
В предыдущем уроке мы разобрали кодировки — они используют знание о типе данных (dictionary для строк, delta для timestamps). Компрессия — следующий шаг: она берёт уже закодированные данные и сжимает их общим алгоритмом, не зная, что внутри.
Два главных trade-off:
- Степень сжатия (compression ratio) — во сколько раз уменьшается размер
- Скорость — как быстро данные сжимаются и разжимаются
Эти два параметра всегда в конфликте. Чем сильнее сжатие, тем дольше compress/decompress.
Четыре главных алгоритма
В мире data engineering доминируют четыре алгоритма компрессии:
Бенчмарки: что выбрать
Типичные цифры на аналитических данных (1 GB колоночных данных после encoding):
| Алгоритм | Compression Ratio | Compress Speed | Decompress Speed | Типичное применение |
|---|---|---|---|---|
| Snappy | 2–3x | ~500 MB/s | ~1.5 GB/s | Spark default, Parquet default |
| LZ4 | 2.5–3.5x | ~500 MB/s | ~2 GB/s | Kafka, ClickHouse |
| Zstd (level 3) | 3.5–5x | ~300 MB/s | ~1 GB/s | Новый default для многих систем |
| GZIP | 3–4.5x | ~50 MB/s | ~300 MB/s | Legacy, HTTP, текстовые форматы |
Бенчмарки зависят от данных. На числовых данных с хорошим encoding разница между алгоритмами минимальна — encoding уже сделал основную работу. На текстовых данных без encoding разница может быть 5x.
Когда какой использовать
Что критичнее?
Первый вопрос: что важнее — скорость запросов или экономия места на диске?Горячие данные, частые reads
Горячие данные читаются часто — каждая миллисекунда декомпрессии умножается на тысячи запросовSnappy / LZ4
Snappy или LZ4 — минимальный overhead на распаковку. Для Kafka-потоков LZ4, для Parquet-файлов Snappy.Холодные данные, архив
Архивные данные читаются редко, но занимают терабайты. Сжатие на 30–50% больше = значительная экономия на S3.Zstd (/ GZIP для legacy)
Zstd даёт лучший баланс. GZIP — только если совместимость с legacy системами обязательна.Правило 2024+: если нет специальных требований — используйте Zstd level 3. Он сжимает лучше Snappy, а распаковывает почти так же быстро. Многие системы переходят на Zstd как default: Delta Lake, Iceberg, новые версии Spark.
Блочная vs страничная компрессия
Компрессия применяется не к файлу целиком, а к блокам (или страницам):
Колонка salary (10M значений)
Колонка разбита на страницы (pages) по ~1 MB. Каждая страница — независимая единица компрессии.Распаковываются только нужные страницы
Если WHERE salary > 100000, движок проверяет min/max статистики каждой страницы и распаковывает только релевантныеБлочная компрессия даёт два преимущества:
- Параллелизм — разные блоки распаковываются разными потоками
- Selective decompression — если нужны только строки 100K–199K, распаковывается только один блок
Цена компрессии: CPU vs Storage
Компрессия экономит storage и network, но тратит CPU. В облаке нужно считать оба:
| Сценарий | Лучший выбор | Почему |
|---|---|---|
| S3 + Athena (pay per scan) | Zstd | Меньше данных = меньше $/TB scanned |
| Kafka (высокий throughput) | LZ4 | Минимальный CPU overhead на producer/consumer |
| Spark (batch processing) | Snappy или Zstd | Snappy — legacy default, Zstd — лучше при тех же ресурсах |
| Архив в Glacier | GZIP или Zstd-19 | Максимальное сжатие, скорость не важна |
| Real-time serving | LZ4 или без компрессии | Каждая микросекунда decompress = P99 latency |
Современные CPU сжимают данные быстрее, чем диск может их записать. Для Snappy/LZ4 компрессия бесплатна — bottleneck на I/O, не на CPU. Zstd на высоких уровнях (10+) — единственный случай, когда CPU становится bottleneck.
Ключевые выводы
- Компрессия работает после кодирования. Кодирование знает тип данных, компрессия — нет.
- Snappy/LZ4 — максимальная скорость, умеренное сжатие. Для hot data и streaming.
- Zstd — лучший баланс. Новый стандарт индустрии. Настраиваемый уровень (1–22).
- GZIP — legacy. Используйте, только если требуется совместимость.
- Блочная компрессия позволяет распаковывать только нужные части файла — критично для predicate pushdown.
- На уже хорошо закодированных данных разница между алгоритмами меньше, чем кажется — основную работу делает encoding.