Learning Platform
Глоссарий Troubleshooting
Урок 14.02 · 22 мин
Начальный
gzipbzip2xzzstdcompression

Форматы сжатия: gzip, bzip2, xz, zstd

Сжатие — это compromise между четырьмя метриками: размер результата, время компрессии, время декомпрессии, и memory usage. Не существует «лучшего» алгоритма — каждый занимает свою точку на этом 4D-tradeoff пространстве.

Для DE нужно знать четыре главных формата: gzip, bzip2, xz, zstd. В этом уроке — что выбрать когда.


Сравнение в одной таблице

Compression формат — characteristics

Trade-offs между размером, скоростью, и совместимостью

gzipСтандарт de facto. С 1992. Везде, везде, везде. Не самое лучшее сжатие, но универсально совместимо
bzip2Лучше сжатие чем gzip. Медленнее (особенно компрессия). С 1996. Утрачивает популярность в пользу xz и zstd
xzLZMA-based. Самое лучшее сжатие из traditional. Очень медленная компрессия. С 2009. Для distribution (Linux kernel tarball — .tar.xz)
zstdFacebook, 2016. Быстрый как gzip, сжатие близкое к xz. De facto стандарт для нового software (Linux kernel modules с 6.x). Идеально для DE

Бенчмарк: 1GB CSV-файл

Примерные цифры (зависят от данных):

ФорматРазмер послеВремя сжатияВремя разжатия
gzip -6 (default)280 MB25 sec5 sec
bzip2 -6220 MB90 sec25 sec
xz -6180 MB180 sec12 sec
zstd -3 (default)250 MB8 sec3 sec
zstd -19 (max)175 MB200 sec3 sec

Главное наблюдение: zstd на дефолтном уровне сжатия — в 3 раза быстрее gzip, и сжимает чуть лучше. На уровне 19 — сжимает как xz, но разжимается в 4 раза быстрее.

Поэтому zstd стал стандартом для нового software: ядро Linux 5.16+ использует zstd для модулей, Docker images используют zstd, btrfs/zfs filesystem compression.

Docker image layers — как zstd связан с OCI image format

gzip — стандарт, доступен везде

# Сжать файл — на месте! Файл заменяется
gzip file.csv
# Результат: file.csv.gz, оригинал удалён

# Сохранить оригинал
gzip -k file.csv
# Результат: file.csv (originally) + file.csv.gz

# Разжать
gunzip file.csv.gz
# Или
gzip -d file.csv.gz

# Прочитать без распаковки
zcat file.csv.gz
gunzip -c file.csv.gz   # синоним

# Уровень сжатия 1-9 (1 = fast/large, 9 = slow/small)
gzip -9 file.csv     # максимальное сжатие
gzip -1 file.csv     # минимальное (быстрое)

# По умолчанию -6
WARNING

gzip удаляет оригинал по умолчанию! Это часто ловит новичков. Команда gzip file.csv приведёт к тому, что file.csv исчезнет, появится file.csv.gz. Используй -k (keep) чтобы оставить оригинал.

Pipe-friendly

# Сжать на лету в pipeline
cat huge.csv | gzip > compressed.csv.gz

# Разжать на лету (для grep/awk)
zcat file.csv.gz | grep "error"
gunzip -c file.csv.gz | awk -F',' '{print $3}'

# Modern shorthand
zgrep "error" file.csv.gz

Эта pipe-friendly особенность — то, почему gzip везде. Tools умеют работать с gzip напрямую.


bzip2 — больше сжатие, медленнее

bzip2 file.csv
# Результат: file.csv.bz2

bunzip2 file.csv.bz2
# или
bzip2 -d file.csv.bz2

# Pipe
bzcat file.csv.bz2 | head
bzip2 -c huge.csv > huge.csv.bz2

bzip2 теряет популярность. Используется в основном для legacy distribution package. Для DE-задач — практически никогда. Если нужно лучше gzip — берите xz или zstd.


xz — лучшее сжатие из traditional

# Сжать (медленно но компактно)
xz file.csv

# Разжать
unxz file.csv.xz
# или
xz -d file.csv.xz

# Pipe
xzcat file.csv.xz
xz -c huge.csv > huge.csv.xz

# Уровни 0-9 (9 = max compression)
xz -9 file.csv

Где используется:

  • Linux kernel distribution (linux-X.Y.Z.tar.xz) — нужно максимальное сжатие при минимальной частоте обновления.
  • Большие software releases где компрессия делается один раз, разжатие много.

Для DE — изредка для long-term archival storage.


zstd — современный король

zstd (Zstandard) — разработан Facebook в 2016, открытый исходный код. Идеален когда нужно «и быстро, и хорошо сжатие, и быстро разжимается».

# Установка (Ubuntu 26.04 идёт со zstd по умолчанию)
sudo apt install zstd
# или
brew install zstd

# Сжать
zstd file.csv
# Результат: file.csv.zst (оригинал сохраняется по умолчанию!)

# Удалить оригинал
zstd --rm file.csv

# Разжать
unzstd file.csv.zst
# или
zstd -d file.csv.zst

# Pipe
zstdcat file.csv.zst
zstd -c huge.csv > huge.csv.zst

# Уровни 1-22 (по умолчанию 3)
zstd -1 file.csv         # самое быстрое
zstd -19 file.csv        # лучше сжатие, медленнее
zstd --long file.csv     # large window (для больших файлов с redundancy)
TIP

zstd по умолчанию сохраняет оригинал (в отличие от gzip!). Это безопаснее. Чтобы удалить оригинал — --rm.

zstd для streaming

# Postgres dump через pipe в zstd
pg_dump dbname | zstd > backup.sql.zst

# Восстановление
zstd -d backup.sql.zst -c | psql dbname
# или (один шаг)
zstdcat backup.sql.zst | psql dbname

Это главный DE-use case для zstd: streaming compression для backup pipelines. Никакого temporary file, всё в pipe.


tar + сжатие: какое выбрать

# tar + gzip — universally compatible
tar czvf backup.tar.gz dir/

# tar + zstd — современный стандарт DE
tar --zstd -cvf backup.tar.zst dir/

# Извлечь zstd
tar --zstd -xvf backup.tar.zst
# Или (modern tar определит по расширению)
tar xvf backup.tar.zst

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

Выбор формата для DE

Какой компромисс важнее в твоём use case

Cross-OS совместимостьЕсли получатели на Windows, macOS, разные Linux версии — gzip есть везде. zstd тоже широко, но иногда нужно специально устанавливать
Speed importantBackup ETL, daily snapshots — нужна скорость. zstd -3 быстрее gzip в 3x и сжимает лучше
Lowest size, infrequentАрхивирование old data, distributing software (compress once, decompress many times) — xz
Database backup pipelinepg_dump | zstd — streaming, нет temp файлов, fast
Legacy / unknown systemsКогда не знаешь, что есть на target — gzip. Везде с 1992 года

DE-сценарии

1. Daily backup Postgres

# Маленькая БД (<10GB)
pg_dump dbname | gzip > backup-$(date +%F).sql.gz

# Большая БД, хочется speed
pg_dump dbname | zstd -3 > backup-$(date +%F).sql.zst

# Очень большая, хочется минимум места (archival)
pg_dump dbname | xz > backup-$(date +%F).sql.xz
# Долго, но небольшой результат

2. Сжатие старых логов

# Сжать все .log файлы старше 7 дней
find /var/log/airflow -name '*.log' -mtime +7 -exec gzip {} \;

# С zstd для нового software
find /var/log/airflow -name '*.log' -mtime +7 -exec zstd --rm {} \;
# --rm удалит оригинал после сжатия

# Параллельное сжатие — быстрее на multi-core
find /var/log -name '*.log' -mtime +7 -print0 | \
  xargs -0 -P 4 -n 1 gzip
# -P 4 — 4 параллельных процесса

3. CSV -> parquet через сжатие

CSV — большой, parquet — компактный native. Но иногда нужно временно сжать CSV для передачи:

# CSV 1GB -> CSV.zst ~200MB
zstd input.csv -o input.csv.zst

# На той стороне обратно
zstdcat input.csv.zst > input.csv

4. Поиск в сжатых логах

# Без распаковки
zgrep "ERROR" /var/log/airflow/*.log.gz

# Streaming через awk
zcat /var/log/airflow/*.log.gz | awk '/ERROR/ {count++} END {print count}'

# Для zstd
zstdgrep "ERROR" /var/log/airflow/*.log.zst
# или
zstdcat /var/log/airflow/*.log.zst | grep "ERROR"

5. Передача больших данных через сеть

# Старый способ: tar + gzip + ssh
tar czf - data/ | ssh remote "cd /target && tar xzf -"

# Современный: zstd для большей скорости
tar --zstd -cf - data/ | ssh remote "cd /target && tar --zstd -xf -"

# С контролем уровня сжатия (баланс CPU vs network)
tar -cf - data/ | zstd -3 | ssh remote "cd /target && zstdcat | tar xf -"

Когда сжатие не помогает

Уже-сжатые данные не сжимаются (или почти не сжимаются):

  • JPEG, PNG, GIF — уже сжаты алгоритмом изображений.
  • MP3, MP4, OGG — уже сжаты media-кодеками.
  • ZIP, GZ, BZ2, XZ, ZST — уже сжаты.
  • Parquet, ORC с compressed columns — уже сжаты.
  • Encrypted данные — выглядят случайно, не сжимаются.

Если попытаетесь сжать image.jpg:

ls -l image.jpg image.jpg.gz
# -rw-r--r-- 1 levo levo 2048543 image.jpg
# -rw-r--r-- 1 levo levo 2049012 image.jpg.gz  # БОЛЬШЕ!

.gz может быть больше оригинала — gzip добавил metadata. Так что не сжимайте сжатое.


Compression ratios — что зависит от данных

Алгоритмы хорошо сжимают данные с redundancy:

  • Text (CSV, JSON, XML, plaintext): 70-90% reduction.
  • Logs: 80-95% reduction (много повторяющихся pattern).
  • HTML: 70-80% reduction.
  • Source code: 60-80% reduction.
  • Random binary: 0-5% reduction.
  • Already compressed: ≈ 0% (или хуже).

DE-наблюдение: ETL processed CSV logs могут сжиматься в 20 раз через zstd с высоким уровнем — потому что много повторяющихся timestamps, IP, user IDs.


Парсинг сжатого файла без полной распаковки

Для огромных файлов — не делать полный gunzip:

# Прочитать первые 100 строк
zcat huge.csv.gz | head -100

# Посчитать строки
zcat huge.csv.gz | wc -l

# AWK обработка
zcat huge.csv.gz | awk -F',' '$3 > 1000 {print}'

# Сжатая sortable стрим
zcat *.csv.gz | sort | uniq -c | sort -rn | head

Поток через zcat не загружает файл целиком в память — он стримит. Можно обрабатывать гигабайты без проблем.


Попробуй сам

# 1. Создай большой текстовый файл
seq 1 1000000 | awk 'BEGIN{srand()} {print $1","rand()*1000","strftime("%Y-%m-%d")}' > /tmp/big.csv

ls -lh /tmp/big.csv

# 2. Сжатие разными форматами
gzip -k -6 /tmp/big.csv     # default level 6
bzip2 -k /tmp/big.csv
xz -k /tmp/big.csv
zstd -k /tmp/big.csv

ls -lh /tmp/big.csv*

# 3. Сравни время
time gzip -k -9 /tmp/big.csv -c > /tmp/big.gz9
time zstd -19 /tmp/big.csv -o /tmp/big.zst19
time xz -k -9 /tmp/big.csv -c > /tmp/big.xz9

ls -lh /tmp/big.{gz9,zst19,xz9}

# 4. Pipe-обработка без распаковки
zcat /tmp/big.csv.gz | head -5
zcat /tmp/big.csv.gz | wc -l
zcat /tmp/big.csv.gz | awk -F',' '$2 > 900 {count++} END {print count}'

# 5. tar + сжатие
mkdir /tmp/dir-test
echo "data" > /tmp/dir-test/file1
echo "data2" > /tmp/dir-test/file2
tar czvf /tmp/test.tar.gz /tmp/dir-test/
tar --zstd -cvf /tmp/test.tar.zst /tmp/dir-test/

ls -lh /tmp/test.tar*

# 6. Cleanup
rm /tmp/big* /tmp/test*
rm -rf /tmp/dir-test

Cross-link: предыдущий урок 01 — tar операции. Следующий урок 03 — zip для совместимости с Windows. Урок 04 — workflows для DE.


Проверка знанийKnowledge check
Объясни trade-offs gzip vs zstd для нового скрипта daily backup БД Postgres на 50GB. Какой выбрать и почему?
ОтветAnswer
Сравнение для этого scenario: gzip — universally compatible (везде, любая система), но slow compression (~10-15 минут для 50GB), default ratio средний. zstd — Facebook 2016, идеален для DE: в 3-5 раз быстрее gzip при том же уровне (или 2x быстрее с лучшим сжатием), декомпрессия очень быстрая. Для 50GB backup: gzip займёт ~10-15 минут CPU, zstd -3 (default) — ~3-5 минут с чуть лучшим сжатием. zstd -19 — близко к xz по размеру, но всё ещё быстрее. Выбор: zstd. Аргументы: 1) Скорость backup критична — short backup window. 2) Disk space — на современных дистрах zstd установлен (Ubuntu 22.04+, Debian 12+, Amazon Linux 2023). 3) Streaming friendly: pg_dump dbname | zstd > backup.sql.zst — без temp файла. 4) Restoration быстрая: zstdcat backup.sql.zst | psql. 5) Это де-facto стандарт для DE на 2024+ — все новые проекты используют zstd. Когда gzip всё ещё лучше: если backup передаётся на старую систему без zstd, если очень важна максимальная совместимость, или для длительного archival (10+ лет — gzip точно будет читаться). Production-команды часто используют zstd для daily backups + gzip для long-term archival. Скрипт: pg_dump $DB | zstd -3 > backup-$(date +%F).sql.zst.

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

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Почему zstd стал предпочтительным для нового software вместо gzip?

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

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

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

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