Я просто провел небольшой эксперимент, где создал архив tar с дубликатами файлов, чтобы посмотреть, будет ли он сжат, к моему ужасу, это не так! Подробности следуют (результаты с отступом для удовольствия от чтения):
$ dd if=/dev/urandom bs=1M count=1 of=a
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.114354 s, 9.2 MB/s
$ cp a b
$ ln a c
$ ll
total 3072
-rw-r--r-- 2 guido guido 1048576 Sep 24 15:51 a
-rw-r--r-- 1 guido guido 1048576 Sep 24 15:51 b
-rw-r--r-- 2 guido guido 1048576 Sep 24 15:51 c
$ tar -c * -f test.tar
$ ls -l test.tar
-rw-r--r-- 1 guido guido 2109440 Sep 24 15:51 test.tar
$ gzip test.tar
$ ls -l test.tar.gz
-rw-r--r-- 1 guido guido 2097921 Sep 24 15:51 test.tar.gz
$
Сначала я создал файл случайных данных размером 1 МБ (а). Затем я скопировал его в файл b и также связал его с c. При создании тарбола tar явно знал о жесткой связи, поскольку тарбол был всего ~ 2MiB, а не ~ 3Mib.
Теперь я ожидал, что gzip уменьшит размер архива до ~ 1 МБ, так как a и b являются дубликатами, и внутри архива должно быть 1 МБ непрерывных данных, но этого не произошло.
Почему это? И как мне эффективно сжать тарбол в этих случаях?
источник
xz -9 -M 95%
или дажеxz -M 95% --lzma2=preset=9,dict=1610612736
. Это не будет быстро, но ваши дубликаты вряд ли останутся в результате.Николь Хэмилтон правильно отмечает, что
gzip
не найдет отдаленные дубликаты данных из-за небольшого размера словаряbzip2
похоже, потому что он ограничен 900 КБ памяти.Вместо этого попробуйте:
Алгоритм LZMA / LZMA2 (
xz
,7z
)Алгоритм LZMA принадлежит тому же семейству, что и Deflate, но использует гораздо больший размер словаря (настраивается; по умолчанию это что-то вроде 384 МБ).
xz
Утилита, которая должна быть установлена по умолчанию в большинстве последних дистрибутивов Linux, аналогичнаgzip
и использует LZMA.Поскольку LZMA обнаруживает избыточность на большие расстояния, она сможет дедуплицировать ваши данные здесь. Однако это медленнее, чем Gzip.
Другой вариант - 7-zip (
7z
вp7zip
пакете), который является архиватором (а не однопотоковым компрессором), который по умолчанию использует LZMA (написанный автором LZMA). 7-zip-архиватор выполняет свою собственную дедупликацию на уровне файлов (просматривая файлы с одинаковым расширением) при архивировании в свой.7z
формат. Это означает, что если вы хотите заменитьtar
на7z
, вы получаете идентичные файлы с дедупликацией. Однако 7z не сохраняет наносекундные временные метки, разрешения или xattrs, поэтому может не соответствовать вашим потребностям.lrzip
lrzip
представляет собой компрессор, который предварительно обрабатывает данные для удаления избыточности на большие расстояния, а затем передает их в обычный алгоритм, такой как Gzip / Deflate, bzip2, lzop или LZMA. Для приведенных здесь образцов данных это необязательно; это полезно, когда входные данные больше, чем могут поместиться в памяти.Для данных такого типа (дублированные несжимаемые фрагменты) вы должны использовать
lzop
сжатие (очень быстрое)lrzip
, поскольку нет смысла пытаться сложнее сжимать полностью случайные данные после их дедупликации.Буп и Обнам
Так как вы помечены на вопрос подпорке , если ваша цель здесь резервное копирование данных, рассмотрите возможность использования дедуплицирующей программы резервной копирования , как БУП или Obnam .
источник
В случае резервного копирования, возможно, с большим набором файлов меньшего размера, одна хитрость, которая может работать для вас, заключается в сортировке файлов в tar по расширению:
источник
rev
(почему даже перевернуть, а затем отсортировать?) И посмотреть наsort
опцию «-r, --reverse» (хотя я не уверен, почему вы даже хотите перевернуть). Но я думаю, что вашtar
вариант "-I
" не делает то, что вы думаете "-I, --use-compress-program PROG
" , вы, вероятно, хотите "-T, --files-from FILE"| tar czf my_archive.tar.gz -I -
должно быть| xargs tar Azf my_archive.tar.gz
rev
меняет порядок символов в каждой строке, а не порядок строк в потоке. Из-за этогоsort
группирует файлы по их расширению. Я подозреваю, что-I -
должен был быть-T -
, который предоставляет список файлов на стандартный ввод.rev
было бы как-то упорядочено по расширению, не то чтобы в linux было много расширений. Я предполагаю, что сортировка по размеру будет иметь больше шансов найтиgzip
не найдет дубликатов, дажеxz
с огромным размером словаря. То, что вы можете сделать, это использоватьmksquashfs
- это действительно сэкономит пространство дубликатов.Некоторые быстрые результаты испытаний с
xz
иmksquashfs
с тремя случайными двоичными файлами (64MB) , из которых два являются одинаковыми:Настроить:
Squashfs:
XZ:
источник
Number of duplicate files found
в stdout.В моей системе
lzma test.tar
получается файл test.tar.lzma размером 106'3175 байт (1.1M)источник
Как дополнение к ответу механической улитки:
Даже xz (или lzma) не найдет дубликаты, если размер несжатого отдельного файла (или, точнее, расстояние между дубликатами) превышает размер словаря. xz (или lzma) даже при самых высоких настройках
-9e
резервирует для этого только 64 МБ.К счастью, вы можете указать свой собственный размер диктонары с помощью опции
--lzma2=dict=256MB
(--lzma1=dict=256MB
допускается только при использовании псевдонима lzma в команде)К сожалению, при переопределении настроек с помощью пользовательских цепочек сжатия, как указано в примере выше, значения по умолчанию для всех остальных параметров не устанавливаются на тот же уровень, что и с -9e. Таким образом, плотность сжатия не так высока для отдельных файлов.
источник
В gzip без ключей командной строки используется минимально возможный алгоритм сжатия.
Попробуйте использовать:
Вы должны получить лучшие результаты
источник