Acabei de fazer um pequeno experimento em que criei um arquivo tar com arquivos duplicados para ver se ele seria compactado, para minha admiração, não era! Detalhes a seguir (resultados recuados para o prazer de ler):
$ 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
$
Primeiro, criei um arquivo de 1MiB de dados aleatórios (a). Depois copiei para um arquivo be também vinculei-o a c. Ao criar o tarball, o tar aparentemente estava ciente do hardlink, já que o tarball tinha apenas ~ 2MiB e não ~ 3Mib.
Agora eu esperava que o gzip reduzisse o tamanho do tarball para ~ 1MiB, já que aeb são duplicados, e deveria haver 1MiB de dados contínuos repetidos dentro do tarball, mas isso não ocorreu.
Por que é isso? E como eu poderia comprimir o tarball com eficiência nesses casos?
fonte
xz -9 -M 95%
, ou mesmoxz -M 95% --lzma2=preset=9,dict=1610612736
. Não será rápido, mas é improvável que suas duplicatas sejam deixadas no resultado.Nicole Hamilton nota corretamente que
gzip
não encontrará dados duplicados distantes devido ao seu pequeno tamanho de dicionário.bzip2
é semelhante, porque está limitado a 900 KB de memória.Em vez disso, tente:
Algoritmo LZMA / LZMA2 (
xz
,7z
)O algoritmo LZMA está na mesma família que Deflate, mas usa um tamanho de dicionário muito maior (personalizável; o padrão é algo como 384 MB). O
xz
utilitário, que deve ser instalado por padrão nas distribuições Linux mais recentes, é semelhante aogzip
e usa LZMA.Como o LZMA detecta redundância de longo alcance, ele pode deduplicar seus dados aqui. No entanto, é mais lento que o Gzip.
Outra opção é o 7-zip (
7z
, nop7zip
pacote), que é um arquivador (em vez de um compressor de fluxo único) que usa o LZMA por padrão (escrito pelo autor do LZMA). O arquivador 7-zip executa sua própria desduplicação no nível do arquivo (observando arquivos com a mesma extensão) ao arquivar em seu.7z
formato. Isto significa que se você está disposto a substituirtar
com7z
, você tem arquivos idênticos desduplicados. No entanto, o 7z não preserva timestamps, permissões ou xattrs em nanossegundos, portanto, pode não atender às suas necessidades.lrzip
lrzip
é um compressor que processa previamente os dados para remover a redundância de longa distância antes de alimentá-los com um algoritmo convencional como Gzip / Deflate, bzip2, lzop ou LZMA. Para os dados de amostra que você fornece aqui, não é necessário; é útil quando os dados de entrada são maiores do que o que pode caber na memória.Para esse tipo de dados (blocos incompressíveis duplicados), você deve usar a
lzop
compactação (muito rápido) comlrzip
, porque não há nenhum benefício em se esforçar mais para compactar dados completamente aleatórios depois de deduplicados.Bup e Obnam
Como você marcou o backup da pergunta , se seu objetivo aqui é fazer backup de dados, considere usar um programa de backup com desduplicação como Bup ou Obnam .
fonte
No caso de um backup, possivelmente com um amplo conjunto de arquivos menores, um truque que pode funcionar para você é classificar os arquivos no tar por extensão:
fonte
rev
assort
opções (por que reverter e depois classificaria?) E olhava para a opção "-r, --reverse" (embora eu não tenha certeza do porquê de querer inversão). Mas acho que suatar
opção "-I
" não faz o que você pensa que faz "-I, --use-compress-program PROG
" , você provavelmente deseja "-T, --files-from FILE"| tar czf my_archive.tar.gz -I -
deveria ser| xargs tar Azf my_archive.tar.gz
rev
inverte a ordem dos caracteres em cada linha, não a ordem das linhas no fluxo. Por essesort
motivo , agrupa os arquivos por sua extensão. Eu suspeito que-I -
deveria ter sido-T -
, o que fornece a lista de arquivos no stdin.rev
meio que arranja por extensão, não que haja muitas extensões no linux de qualquer maneira. Eu imagino a classificação por tamanho teria uma chance maior de encontrar dup degzip
não encontrará duplicatas, mesmoxz
com um tamanho enorme de dicionário. O que você pode fazer é usarmksquashfs
- isso economizará o espaço de duplicatas.Alguns resultados rápidos de testes com
xz
emksquashfs
com três arquivos binários aleatórios (64 MB), dos quais dois são iguais:Configuração:
Squashfs:
xz:
fonte
Number of duplicate files found
no stdout.No meu sistema,
lzma test.tar
resulta em um arquivo test.tar.lzma de 106'3175 bytes (1,1M)fonte
Como complemento à resposta do 'caracol mecânico:
Mesmo xz (ou lzma) não encontrará duplicatas se o tamanho do arquivo único não compactado (ou, mais precisamente, a distância entre as duplicatas) exceder o tamanho do dicionário. xz (ou lzma), mesmo na configuração mais alta,
-9e
reserva apenas 64 MB para isso.Felizmente, você pode especificar seu próprio tamanho dictonário com a opção
--lzma2=dict=256MB
(somente--lzma1=dict=256MB
é permitida ao usar o alias lzma no comando)Infelizmente, ao substituir as configurações por cadeias de compactação personalizadas, como fornecido no exemplo acima, os valores padrão para todos os outros parâmetros não são definidos no mesmo nível que com -9e. Portanto, a densidade de compactação não é tão alta para arquivos únicos.
fonte
O gzip sem opções de linha de comando usa o algoritmo mais baixo possível para compactação.
Tente usar:
Você deve obter melhores resultados
fonte