Что реально сжимается: логи, JPEG, базы и видео в цифрах
Диск заполнился, и первая мысль — «давайте всё заархивируем, сжатие же экономит место». Через час CPU занят на 100%, архив собирается медленно, а итоговый файл почти не отличается по размеру от исходной папки. Проблема не в выборе алгоритма и не в настройках — вы просто попытались сжать то, что сжимать уже бессмысленно. Разберём, какие данные на сервере реально дают выигрыш от сжатия, какие — нет, и почему это не вопрос удачи, а прямое следствие того, как устроены форматы и алгоритмы.
Содержание
- Почему одни данные сжимаются, а другие — почти нет
- Логи и конфиги: где сжатие реально работает
- Дампы баз данных: текстовый SQL против уже сжатых бэкапов
- JPEG, MP4, ZIP и другие форматы, где повторное сжатие не работает
- Эксперимент: что покажет попытка сжать уже сжатое
- Практический вывод: куда тратить время сжатия, а куда нет
Почему одни данные сжимаются, а другие — почти нет
В основе любого сжатия без потерь (gzip, zstd, xz, deflate внутри ZIP) лежит один и тот же принцип: алгоритм ищет избыточность — повторяющиеся последовательности байт, предсказуемые паттерны, статистические перекосы (одни символы или блоки встречаются намного чаще других). Найденную избыточность он заменяет более компактной записью: вместо «повторить эту фразу 40 раз» — короткая ссылка на уже встреченный фрагмент плюс счётчик повторов. Это упрощение, но суть механики именно такая — что у deflate внутри gzip, что у более современных LZ77-производных алгоритмов вроде zstd.
Отсюда прямое следствие: чем больше в данных предсказуемых, повторяющихся кусков — тем больше есть что сжимать. А если избыточность из данных уже удалили на предыдущем этапе — искать алгоритму нечего, и результат сжатия почти не отличается от исходного размера.
Это не абстрактная теория — она напрямую делит все данные на сервере на две практические группы:
- Данные, где избыточность ещё есть — текстовые логи, дампы баз в текстовом формате, конфиги, исходный код, JSON/XML/CSV. Их никто специально не «уплотнял» перед записью на диск.
- Данные, где избыточность уже убрали — JPEG, PNG, MP4, MP3, уже собранные ZIP/RAR/7z-архивы, зашифрованные файлы. Здесь работу по удалению избыточности уже сделал кодек или сам формат в момент создания файла, ещё до того, как файл попал на ваш диск.
Дальше — предметно по каждой категории, с конкретными командами и без выдуманных цифр там, где точный коэффициент зависит от содержимого.
Логи и конфиги: где сжатие реально работает
Текстовые логи — один из самых благодарных типов данных для сжатия вообще, и вот почему: строка лога почти всегда повторяет структуру соседних строк. Одинаковые метки времени с точностью до формата, ограниченный набор уровней (INFO, WARN, ERROR), повторяющиеся имена полей, IP-адреса и user-agent'ы, которые встречаются десятками раз за минуту. Это именно та регулярность, на которой алгоритм экономит байты.
# типичный access-лог nginx
ls -la access.log
gzip -9 -k access.log
ls -la access.log access.log.gz
Конкретный коэффициент сжатия для вашего лога зависит от того, насколько он однороден: чем более шаблонные строки и чем меньше в них уникальных данных (например, произвольных ID запросов или полезной нагрузки в base64), тем сильнее он сожмётся. Точную цифру для своих логов проверяйте сами — не берите на веру усреднённые проценты из чужих статей (в том числе из этой), они посчитаны на другом содержимом.
На практике для логов почти всегда стоит сжимать хотя бы отработанные файлы после ротации — базовый logrotate делает это без дополнительных настроек:
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
}
delaycompress откладывает сжатие последнего архива на один цикл ротации — это нужно не для экономии места, а чтобы приложение успело закрыть файловый дескриптор старого лога и не писало в уже переименованный файл. Подробнее про весь жизненный цикл — что писать, когда сжимать, когда удалять окончательно — разобрано в регламенте хранения логов.
Для больших объёмов логов зачастую выгоднее zstd вместо классического gzip — сопоставимая или лучшая степень сжатия при заметно более высокой скорости, особенно с многопоточным режимом:
zstd -T0 -19 --long=27 access.log -o access.log.zst
Уровень сжатия здесь тоже не бесплатный параметр — рост с дефолтного уровня до максимального часто съедает много CPU-времени ради небольшой экономии места. Механика этого компромисса отдельно разобрана в статье про уровни сжатия и что вы платите, поднимая цифру — для логов на ежедневной ротации обычно достаточно среднего уровня, а не максимального.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверДампы баз данных: текстовый SQL против уже сжатых бэкапов
Здесь важно различать два принципиально разных случая, которые легко перепутать.
Текстовый дамп (mysqldump, pg_dump без -Fc) — это по сути огромный текстовый файл с SQL-командами: повторяющиеся INSERT INTO, одни и те же имена колонок на каждой строке, однотипные типы данных, часто повторяющиеся значения (статусы, категории, внешние ключи). Это классический кандидат на хорошее сжатие — та же логика, что и с логами.
mysqldump --single-transaction mydb | gzip -9 > mydb.sql.gz
# или через zstd с многопоточностью на больших базах
mysqldump --single-transaction mydb | zstd -T0 -19 -o mydb.sql.zst
Бэкап, который уже сжат средствами самой утилиты — другая история. pg_dump с ключом -Fc (custom format) по умолчанию уже применяет сжатие внутри своего формата. percona xtrabackup с флагом --compress тоже сжимает поток на лету. Инструменты дедупликации и архивации вроде borg или restic сами сжимают блоки перед записью в репозиторий. Если вы прогоните такой файл ещё раз через gzip снаружи — вы не экономите место, а тратите CPU и время на проверку того, что и так уже плотно упаковано.
# уже сжатый вывод — повторное сжатие снаружи не даёт смысла
pg_dump -Fc mydb -f mydb.dump
gzip mydb.dump # почти не уменьшит файл, только добавит время
Практическое правило простое: если инструмент бэкапа сам умеет сжимать — включайте сжатие один раз, на этом уровне, и не оборачивайте результат в ещё один слой архивации. Если дампите в текстовый SQL — сжимайте снаружи, там есть реальный выигрыш. Таблицы внутри самой базы устроены похоже: поля с ограниченным набором значений (статусы, категории, внешние ключи) и текстовые поля сжимаются заметно, а уже сжатые BLOB-поля или зашифрованные столбцы — почти никак, вне зависимости от того, каким инструментом вы сжимаете файл дампа снаружи.
JPEG, MP4, ZIP и другие форматы, где повторное сжатие не работает
Это зеркальная ситуация к логам. JPEG уже на этапе кодирования проходит через дискретное косинусное преобразование, квантование и энтропийное кодирование — то есть избыточность из изображения выжимается прямо в момент создания файла, а не оставляется «на потом». То же с видео: кодеки вроде H.264/H.265 используют компенсацию движения между кадрами и собственное энтропийное кодирование — они уже нашли и убрали практически всю статистическую избыточность, которую в принципе можно найти в этих данных без потери качества.
Похожая история с уже собранными архивами. ZIP, RAR, 7z, а также любой файл, который уже прогнали через gzip или zstd — это результат применения того же самого класса алгоритмов, которые вы бы использовали для повторного сжатия. Пытаться сжать уже сжатый архив — это по сути прогнать deflate через данные, которые уже прошли deflate (или похожий по духу алгоритм) один раз. Второй проход почти ничего не находит.
К этой же группе стоит отнести зашифрованные данные — шифрование по своей конструкции превращает исходные данные в поток, статистически неотличимый от случайного шума, а случайный шум — это ровно то, на чём алгоритм сжатия бессилен по определению: там нет закономерностей, которые можно было бы найти.
Практический риск повторного сжатия таких данных — не только потраченное время. У форматов сжатия есть собственные накладные расходы: заголовки, контрольные суммы, служебные блоки. У gzip, например, это фиксированный заголовок и футер вокруг сжатого потока. Если исходные данные несжимаемы, алгоритм добросовестно пытается их сжать, не находит выигрыша — и в сумме итоговый файл оказывается на несколько байт-килобайт больше исходного, просто за счёт этой служебной обвязки. Не катастрофа по объёму, но наглядная иллюстрация того, что «сжать ещё раз на всякий случай» — не бесплатная страховка, а гарантированная трата CPU без пользы, а иногда и с небольшим минусом по месту.
Эксперимент: что покажет попытка сжать уже сжатое
Не верьте цифрам из статей (включая эту) — проверить разницу на своих файлах занимает пару минут и снимает все вопросы.
# берём текстовый файл и уже сжатое изображение для сравнения
ls -la dump.sql photo.jpg
gzip -9 -k dump.sql
gzip -9 -k photo.jpg
ls -la dump.sql dump.sql.gz photo.jpg photo.jpg.gz
На текстовом дампе вы почти наверняка увидите заметное сокращение размера — конкретный коэффициент зависит от содержимого, но разница будет видна невооружённым глазом в выводе ls -la. На JPEG — файл .gz окажется примерно того же размера, что и оригинал, а может оказаться на несколько байт больше. Это ожидаемый и правильный результат, а не баг gzip: алгоритм добросовестно попробовал сжать, не нашёл избыточности и просто упаковал данные почти без изменений (плюс служебная обвязка формата).
Тот же эксперимент можно провести на уровне файловой системы, если у вас есть ZFS с включённым сжатием — метрика compressratio на датасете с логами и на датасете с медиатекой покажет ту же разницу, только для всего объёма данных сразу, без ручного прогона gzip по отдельным файлам. Подробный разбор того, как это работает на уровне блоков и как читать метрики — в статье про сжатие в ZFS и на каких данных оно реально экономит место.
Похожий эффект возникает и на уровне HTTP-ответов: если сервер пытается на лету сжимать уже сжатый контент (изображения, видео, ранее заархивированные файлы для скачивания), CPU тратится на попытку компрессии, которая заведомо ничего не даст — про эту конкретную ловушку и её цену подробно написано в статье про сжатие на лету и когда оно того не стоит.
Практический вывод: куда тратить время сжатия, а куда нет
Из всего разобранного выше следует простое правило приоритизации, которое экономит и место на диске, и CPU-время: не пытайтесь сжимать всё подряд одним общим проходом. Разделите данные на категории заранее и обрабатывайте их по-разному.
| Тип данных | Стоит ли сжимать отдельно | Почему |
|---|---|---|
| Текстовые логи, JSON/CSV-выгрузки | Да | Много повторяющихся паттернов |
Текстовые дампы БД (mysqldump, pg_dump без -Fc) | Да | Повторяющаяся SQL-структура |
| Конфиги, исходный код, документация | Да | Текст с ограниченным набором конструкций |
Бэкапы с собственным сжатием (-Fc, --compress, borg/restic) | Нет | Уже сжаты внутри инструмента |
| JPEG, PNG (оптимизированные), MP4, MP3 | Нет | Избыточность убрана кодеком при создании |
| Готовые ZIP/RAR/7z-архивы | Нет | Тот же класс алгоритмов уже применён |
| Зашифрованные файлы и диски | Нет | Данные статистически неотличимы от шума |
Если у вас на сервере есть общий скрипт архивации (например, tar перед выгрузкой в холодное хранилище), имеет смысл явно исключить из общего сжатия каталоги с уже сжатым контентом — это ускоряет сборку архива и не портит итоговый размер накладными расходами:
tar --exclude='*.jpg' --exclude='*.mp4' --exclude='*.zip' \
-cf - /var/www/app | zstd -T0 -19 -o app-backup.tar.zst
Медиатеку, каталог с готовыми бэкапами и зашифрованные разделы в таком скрипте разумнее архивировать вообще без сжатия (tar -cf без -z) — просто как способ собрать много файлов в один поток для передачи, без бесполезной траты CPU на попытку их уплотнить. А ресурсы, которые вы бы потратили на сжатие несжимаемого, лучше направить туда, где эффект реально измеряется в разах, а не в долях процента — на логи, дампы и конфигурации.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Стоит ли специально сжимать JPEG или MP4 перед загрузкой на сервер, чтобы сэкономить место?
Общим архиватором (gzip/zstd/7z) — нет, эффекта почти не будет. Если нужно уменьшить именно медиафайл, это делается специализированными инструментами для конкретного формата (перекодирование видео с другим битрейтом, пересжатие JPEG с потерей качества через jpegoptim или аналогичные), а не универсальным архиватором — это разные задачи с разными компромиссами.
Почему ZIP-архив из уже сжатых файлов иногда получается чуть больше суммы исходников?
Потому что архиватор честно пытается сжать каждый файл, не находит избыточности, но всё равно добавляет служебную обвязку формата — заголовки записей, контрольные суммы, метаданные. На несжимаемых данных эта обвязка не компенсируется выигрышем от сжатия, и итог оказывается немного больше исходного объёма.
Можно ли доверять готовым процентам экономии места из статей в интернете, включая эту?
Нет — реальный коэффициент сжатия зависит от конкретного содержимого ваших файлов: насколько однородны логи, насколько «текстовая» база, сколько уникальных данных в каждой записи. Единственный надёжный способ узнать цифру — прогнать сжатие на своих данных и сравнить размер до и после.
Как быстро проверить, стоит ли овчинка выделки для конкретной папки на сервере?
Возьмите несколько репрезентативных файлов, сожмите их вручную (gzip -9 -k файл) и сравните размер через ls -la. Если сжатая версия меньше на заметную долю — сжатие имеет смысл ставить на регулярную основу для этой папки. Если размер почти не изменился или вырос — не тратьте на это CPU и место под второй экземпляр файла.
Замедлит ли попытка сжать несжимаемые данные общий бэкап сервера?
Да, и заметно — CPU потратит время на анализ каждого блока в поисках избыточности, которой там нет, а в результате вы получите файл почти того же размера. На больших объёмах медиаданных или уже готовых архивов это может ощутимо растянуть окно бэкапа без какой-либо пользы по месту.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →