Прямой ответ
Zstd поддерживает диапазон уровней сжатия, где низкие уровни дают высокую скорость при умеренном коэффициенте, а высокие — больший коэффициент при заметно большем времени.
| Уровень | Характер | Когда применяется |
|---|---|---|
| 1–3 | Быстрое сжатие | Потоковая обработка, частая запись |
| 4–9 | Сбалансированное | Хранение с периодическим чтением |
| 10–19 | Высокий коэффициент | Архивация, редкое чтение |
# Сравнение уровней на одном файле
for lvl in 1 3 9 19; do
zstd -$lvl -c data.json > data.$lvl.zst
done
ls -l data.*.zst
# Распаковка
zstd -d -c data.9.zst > data.json
Коэффициент сжатия измеряется как отношение исходного размера к сжатому; о методике — в статье про оценку коэффициента.
Выбор уровня определяется тем, что ограничивает: объём хранения либо время обработки. О соотношении параметров — в статье про выбор алгоритма сжатия.
Словари для малых порций и потоковое сжатие
Два механизма расширяют применимость zstd за пределы сжатия больших файлов.
Словари. Заголовок алгоритма занимает фиксированный объём, поэтому на малых порциях сжатие неэффективно. Словарь, обученный на выборке данных того же вида, содержит частые шаблоны, поэтому малая порция сжимается эффективнее.
Потоковое сжатие. Данные сжимаются по мере поступления, поэтому весь объём не требуется держать в памяти. Применяется при обработке больших наборов и передаче данных.
Практическое следствие: словарь имеет смысл при сжатии множества малых объектов одного вида, например записей журнала либо небольших документов.
# Обучение словаря на выборке файлов
zstd --train samples/*.json -o dict.json
# Сжатие с использованием словаря
zstd -D dict.json -c record.json > record.json.zst
Отдельный аспект — скорость распаковки. Распаковка выполняется быстрее сжатия и её скорость мало зависит от уровня, поэтому данные, сжатые на высоком уровне, читаются почти так же быстро. Асимметрия позволяет выбирать высокий уровень для данных с редким чтением.
О применении zstd к журналам приложений — в статье про сжатие логов.
Потребление памяти растёт с уровнем, поскольку алгоритм удерживает большее окно данных. При ограниченной памяти уровень выбирается с учётом доступного объёма.
Многопоточное сжатие и пакетная обработка
Zstd поддерживает многопоточное сжатие, поэтому время обработки больших файлов сокращается при наличии нескольких ядер.
Параллельные потоки. Данные делятся на части, которые сжимаются одновременно, поэтому время сжатия сокращается пропорционально числу потоков при достаточном объёме данных.
Влияние на коэффициент. Коэффициент при многопоточном сжатии может незначительно отличаться, поскольку каждая часть сжимается независимо и шаблоны не переносятся между частями.
Пакетная обработка. Множество малых файлов сжимаются в одном процессе, поэтому накладные расходы на запуск распределяются, а словарь применяется ко всем файлам пакета.
Практическое следствие: многопоточное сжатие выгодно для больших объёмов, где время обработки ограничивает конвейер. Для малых файлов выигрыш определяется пакетной обработкой, а не числом потоков.
Отдельный аспект — потребление памяти. Каждый поток удерживает собственное окно данных, поэтому общее потребление памяти растёт с числом потоков и уровнем сжатия.
Практика: настройка zstd под задачу
1. Определите ограничение. Объём хранения либо время обработки определяет выбор уровня.
2. Измерьте несколько уровней на своих данных. Коэффициент зависит от избыточности, поэтому тест на чужих данных не переносится.
3. Используйте словарь для малых порций. Обученный словарь содержит частые шаблоны, поэтому малые объекты сжимаются эффективнее.
4. Применяйте потоковое сжатие для больших наборов. Весь объём не требуется держать в памяти.
5. Учитывайте потребление памяти. Уровень сжатия определяет размер окна, поэтому при ограниченной памяти уровень снижается.
6. Фиксируйте уровень в конфигурации. Изменение уровня влияет на время и объём, поэтому значение задаётся явно.
7. Проверяйте скорость распаковки. Данные с частым чтением требуют быстрой распаковки, которая мало зависит от уровня.
Рекомендации:
- Различайте сжатие и распаковку по стоимости. Распаковка быстрее сжатия, поэтому асимметрия учитывается при выборе уровня.
- Обучайте словарь на репрезентативной выборке. Словарь, обученный на нерелевантных данных, не даёт выигрыша.
- Не используйте максимальный уровень по умолчанию. Время сжатия растёт заметно, а прирост коэффициента на высоких уровнях уменьшается.
- Проверяйте совместимость версии формата. Файлы, сжатые новой версией, должны распаковываться имеющимися инструментами.
- Пересматривайте уровень при изменении данных. Изменение состава данных изменяет избыточность и коэффициент сжатия.
Практический сценарий: сжатие на максимальном уровне замедлило конвейер
Контекст: конвейер обработки данных выполнялся значительно дольше после включения сжатия на высоком уровне.
- Диагностика. Уровень сжатия установлен максимальным, время сжатии выросло в несколько раз, а прирост коэффициента относительно среднего уровня составил несколько процентов. Распаковка выполнялась с той же скоростью.
- Причина. На высоких уровнях время сжатия растёт заметно, а прирост коэффициента уменьшается. Данные читались часто, поэтому выигрыш в объёме не компенсировал увеличение времени обработки.
- Действия. (а) Измерили коэффициент и время на нескольких уровнях для фактических данных; (б) выбрали уровень, при котором прирост коэффициента ещё заметен, а время приемлемо; (в) для данных с редким чтением оставили высокий уровень, поскольку распаковка не замедляется; (г) обучили словарь для малых записей, что повысило коэффициент без роста уровня; (д) зафиксировали уровни в конфигурации с указанием назначения.
- Результат. Время конвейера вернулось к приемлемому, а объём хранения сократился за счёт словаря для малых записей.
Вывод: максимальный уровень сжатия даёт малый прирост коэффициента при заметном росте времени. Измерение на фактических данных позволяет выбрать уровень, соответствующий ограничению задачи.
FAQ
Какой уровень zstd выбрать по умолчанию? Определяется измерением на собственных данных. Низкие уровни подходят для частой записи, высокие — для архивации с редким чтением.
Замедляет ли высокий уровень распаковку? Незначительно. Скорость распаковки мало зависит от уровня, поэтому данные с высоким уровнем читаются почти так же быстро.
Когда нужен словарь? При сжатии множества малых объектов одного вида. Заголовок алгоритма занимает фиксированный объём, поэтому на малых порциях словарь даёт заметный выигрыш.
Влияет ли уровень на потребление памяти? Да, уровень определяет размер окна данных, удерживаемого алгоритмом. При ограниченной памяти уровень снижается.
Источники: Zstandard, zstd manual, zstd man page — ссылки в шапке.