MAATRIX / Блог / Сжатие в ZFS: сколько реально экономит на разных данных

Сжатие в ZFS: сколько реально экономит на разных данных

MAATRIX

Включили сжатие на ZFS-датасете, ждёте, что диск освободится в разы — а compressratio показывает жалкие 1.02x. Или наоборот, боитесь включать сжатие на проде, потому что где-то читали про «нагрузку на CPU». Оба страха и обе надежды упираются в один факт: эффект сжатия в ZFS определяется не настройками, а тем, что именно вы храните. Разберём честно, без усреднённых цифр из чужих бенчмарков.

Как устроено сжатие в ZFS

Сжатие в ZFS работает на уровне блоков, прозрачно для приложений — ни одна программа, которая пишет файлы в датасет, не знает и не должна знать о том, что данные сжимаются. Это встроенная функция файловой системы/тома, а не отдельный процесс архивации.

Механика простая: при записи блока ZFS пробует сжать его выбранным алгоритмом. Если сжатый блок оказывается заметно меньше — на диск уходит сжатая версия, плюс метаданные о том, каким алгоритмом и до какого размера. Если сжатие не даёт выигрыша (блок уже плотный по энтропии) — ZFS просто пишет блок как есть, без насильственного сжатия «через силу». При чтении процесс идёт в обратную сторону: блок расжимается в памяти прозрачно для приложения.

Включается сжатие свойством датасета, без пересоздания пула:

zfs set compression=on tank/data

Значение on в современных версиях ZFS маппится на алгоритм lz4 — он давно является дефолтом не просто «на бумаге», а по факту используется почти повсеместно, потому что даёт хороший баланс между скоростью (сжатие и расжатие быстрее, чем скорость самого диска почти всегда) и степенью сжатия. Есть и другие варианты — gzip с уровнями 1-9 (сильнее сжимает, но заметно медленнее и грузит CPU сильнее), zstd в свежих версиях OpenZFS (гибче, можно тонко настраивать уровень). Но если не углубляться в тюнинг — lz4 в подавляющем большинстве сценариев остаётся разумным выбором по умолчанию.

Важный нюанс: свойство compression применяется только к новым записям. Если включили сжатие на датасете, где уже лежат терабайты данных — старые блоки останутся несжатыми, пока их не перепишут. Чтобы пересжать существующие данные, нужно либо переписать файлы (скопировать и заменить), либо сделать zfs send | zfs receive в новый датасет с уже включённым сжатием.

Данные, которые сжимаются хорошо

Текстовая и слабоструктурированная информация обычно содержит существенную избыточность — повторяющиеся паттерны, предсказуемые последовательности символов, много «воздуха» в виде пробелов, разделителей, повторяющихся ключевых слов. Алгоритмы сжатия на этом и работают: чем регулярнее структура данных, тем сильнее они схлопываются.

Сюда попадает:

  • Логи — однотипные строки, повторяющиеся timestamp-форматы, одинаковые уровни (INFO, ERROR), похожие сообщения. Логи — один из самых благодарных кандидатов на сжатие вообще.
  • Исходный код — текстовые файлы с ограниченным набором ключевых слов, отступами, повторяющимися конструкциями.
  • Конфиги, JSON, XML, CSV — структурированный текст с предсказуемыми полями и разделителями.
  • Некоторые форматы баз данных — таблицы с большим количеством повторяющихся значений (статусы, категории, внешние ключи) или текстовых полей сжимаются заметно; таблицы с уже плотными бинарными полями или зашифрованными данными — заметно хуже.

На датасетах такого типа отчёт zfs get compressratio обычно показывает заметный выигрыш — именно «заметный», а не какое-то фиксированное число, потому что реальная степень сжатия зависит от конкретного содержимого: насколько однородны логи, насколько «текстовый» код, насколько разрежены таблицы. Обещать конкретный процент без проверки на своих данных — вводить в заблуждение.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Данные, которые сжимаются плохо или никак

Обратная сторона: данные, которые уже прошли через собственный алгоритм сжатия, для ZFS выглядят как высокоэнтропийный шум — без явных повторяющихся паттернов, которые можно было бы схлопнуть.

  • Видео (H.264, H.265 и подобные кодеки) — сжато на уровне кодека, повторное сжатие почти ничего не даёт.
  • Изображения в JPEG, PNG (уже оптимизированные), WebP — та же история, данные уже плотные.
  • Архивы ZIP, RAR, 7z, GZIP-бэкапы — если бэкап уже прогнан через gzip или zstd перед записью на диск, ZFS почти нечего сжимать повторно.
  • Зашифрованные данные — шифрование по конструкции превращает данные в псевдослучайный набор байт, тут сжатие бессильно почти по определению.

На таких датасетах compressratio будет близок к 1.00x — то есть выигрыша по месту почти нет. ZFS в этом случае достаточно умна, чтобы не сжимать блок насильно, если сжатый результат не даёт экономии — она просто хранит блок как есть. Но сама попытка сжатия (проверка, стоит ли овчинка выделки) требует крохотных, но не нулевых тактов CPU на каждую запись. На современном железе и с lz4 это почти всегда несущественно, но если у вас датасет из чисто уже сжатых данных и CPU и так под нагрузкой — отключить сжатие для него разумно, ощутимого убытка вы не понесёте.

Виртуальные диски VM: it depends

Это самый неоднозначный случай, и здесь общих цифр из интернета доверять точно не стоит. Виртуальный диск (qcow2, raw-образ на zvol, VMDK) с точки зрения ZFS — это один большой файл или блочное устройство. Насколько он сожмётся, целиком зависит от того, что лежит внутри гостевой файловой системы.

  • Если внутри VM — обычная система с текстовыми конфигами, логами, исходным кодом, базой данных с типичной текстовой нагрузкой — сжатие даёт заметный эффект, аналогично прямому хранению такого же контента на хосте.
  • Если внутри VM крутится сервис, который сам хранит уже сжатые данные (медиасервер с видеотекой, S3-совместимое хранилище с архивами, база с уже сжатыми BLOB-полями) — эффект слабый, почти как для видео и архивов напрямую.
  • Есть и промежуточный эффект от самого формата: у диска в разреженном (thin-provisioned) состоянии много блоков состоит из нулей — это тоже прекрасно сжимается почти в ноль, но это не «сжатие полезных данных», а эффект пустого места, которое ещё не занято.

Практический вывод: не пытайтесь угадать эффект для VM-диска заранее по типу гипервизора или формата образа — смотрите на то, что реально пишет в диск гостевая ОС. Если не уверены в составе данных внутри VM — включайте сжатие всё равно (оно не повредит) и смотрите на факт через compressratio после недели реальной работы.

Методика: что делать со своими датасетами

Не пытайтесь угадать эффект заранее — универсальный рецепт таков:

  1. Датасет с преимущественно несжимаемыми данными (видеоархив, готовые ZIP-бэкапы, хранилище уже сжатых медиафайлов) — сжатие можно смело отключать, вы ничего не теряете по месту, а экономите крохи CPU на попытках сжатия, которые всё равно ничего не дадут:
   zfs set compression=off tank/media
  1. Датасет с текстовыми/логовыми/конфигурационными данными (логи приложений, git-репозитории, конфиги, большинство баз данных общего назначения) — включайте сжатие почти всегда. Накладные расходы CPU у lz4 на современном железе обычно не заметны на фоне выигрыша по месту:
   zfs set compression=lz4 tank/logs
  1. Не уверены, что за данные — включайте lz4 по умолчанию (это разумный дефолт для смешанной нагрузки) и проверяйте сами через какое-то время реальной работы:
   zfs get compressratio tank/data

Значение 1.00x значит «сжатие почти ничего не даёт, можно выключить ради экономии CPU». Значение заметно выше 1.00x значит «сжатие работает, оставляем». Конкретные пороги для «стоит ли овчинка выделки» зависят от того, насколько для вас критичен CPU — если он не узкое место, можно оставлять сжатие включённым даже при скромном compressratio, лишний надёжный запас места редко мешает.

Дополнительно полезно смотреть на zfs get used,logicalused — разница между used (реально занято на диске) и logicalused (сколько заняли бы данные без сжатия) наглядно показывает эффект в абсолютных цифрах, а не только в виде коэффициента.

zfs get compressratio,used,logicalused tank/data

Никогда не полагайтесь на цифры «ZFS экономит X% места» из статей в интернете (включая эту) как на готовый прогноз для вашего конкретного датасета — они посчитаны на чужих данных с чужой структурой. Единственный надёжный способ узнать реальную экономию — включить сжатие и измерить на своих данных.

Что с этим на арендованном сервере

Если вы разворачиваете хранилище на арендованном VPS или выделенном сервере под ZFS, вопрос сжатия стоит решить сразу при создании датасетов, ещё до того, как туда попадут терабайты данных — тогда не придётся потом гонять zfs send/receive только ради пересжатия старых блоков. Для смешанной нагрузки (система + логи + база + бэкапы) разумно с самого начала поставить compression=lz4 на уровне корневого датасета пула — он унаследуется дочерними датасетами, если явно не переопределить, — а для отдельных поддатасетов с заведомо несжимаемым контентом (медиатека, готовые архивы) выставить compression=off точечно.

Отдельные материалы по смежным темам хранилища на сервере — про то, как устроены снапшоты в Proxmox (снапшоты ZFS и copy-on-write работают по похожему принципу), про выбор типа хранилища при разворачивании гипервизора — хранилища в Proxmox: что и когда, и про смежный эффект copy-on-write на других форматах — почему тормозит снапшот в qcow2.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Нужно ли отдельно сжимать данные перед записью в ZFS с включённым compression?

Нет, и делать этого не стоит — сжатие ZFS прозрачно работает на уровне блоков при записи, ручное предварительное сжатие файлов только добавит CPU-нагрузку на вашей стороне и ухудшит и без того слабый эффект (сжатое дважды не сожмётся сильнее).

Просядет ли скорость диска от включённого сжатия?

На современном железе с lz4 в большинстве случаев нет — алгоритм спроектирован так, чтобы сжатие и расжатие происходили быстрее, чем реальная скорость чтения/записи на диск, поэтому суммарно сжатие часто даже ускоряет операции (меньше физических блоков нужно прочитать/записать). С gzip на высоких уровнях эффект на CPU заметнее, там компромисс нужно оценивать под конкретную нагрузку.

Можно ли одновременно использовать сжатие и шифрование ZFS?

Да, порядок операций в ZFS — сначала сжатие, потом шифрование, поэтому сжатие успевает сработать на исходных данных до того, как они превратятся в псевдослучайные байты от шифрования. Просто не ждите высокого compressratio, если сами исходные данные уже были плотными (видео, архивы) до шифрования.

Что будет, если включить сжатие на датасете, где уже лежат данные?

Ничего не сломается, но и старые блоки не пересожмутся сами — свойство compression действует только на новые записи. Чтобы применить сжатие к уже лежащим данным, нужно их переписать (скопировать заново) или перенести через zfs send | zfs receive в датасет с уже включённым сжатием.

Почему compressratio показывает не то, что я ожидал по «общим цифрам из интернета»?

Потому что общие цифры считаются на чужих данных с другой структурой избыточности. compressratio — это измерение по вашим реальным данным, и это единственное число, которому стоит доверять для планирования места именно на вашем сервере.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →