Właśnie wykonałem mały eksperyment, w którym utworzyłem archiwum tar ze zduplikowanymi plikami, aby sprawdzić, czy będzie ono skompresowane, ku mojemu podziwowi, nie było! Szczegóły poniżej (wyniki wcięte dla przyjemności czytania):
$ 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
$
Najpierw stworzyłem plik 1 MB losowych danych (a). Następnie skopiowałem go do pliku b, a także połączyłem go do c. Podczas tworzenia tarballa, tar najwyraźniej był świadomy twardego linku, ponieważ tarball miał tylko ~ 2MiB, a nie ~ 3Mib.
Teraz spodziewałem się, że gzip zmniejszy rozmiar tarballa do ~ 1MiB, ponieważ aib są duplikatami, a wewnątrz tarballa powinien być powtarzany 1MiB ciągłych danych, ale tak się nie stało.
Dlaczego to? I w jaki sposób mogę skutecznie skompresować archiwum w tych przypadkach?
źródło
xz -9 -M 95%
, a nawetxz -M 95% --lzma2=preset=9,dict=1610612736
. Nie będzie to szybkie, ale twoje duplikaty raczej nie zostaną w wyniku.Nicole Hamilton poprawnie zauważa, że
gzip
ze względu na mały rozmiar słownika nie znajdzie odległych zduplikowanych danych.bzip2
jest podobny, ponieważ jest ograniczony do 900 KB pamięci.Zamiast tego spróbuj:
Algorytm LZMA / LZMA2 (
xz
,7z
)Algorytm LZMA należy do tej samej rodziny co Deflate, ale wykorzystuje znacznie większy rozmiar słownika (konfigurowalny; domyślnie jest to około 384 MB).
xz
Narzędzie, które powinny być instalowane domyślnie w najnowszych dystrybucjach systemu Linux, jest podobny dogzip
i używa lzma.Ponieważ LZMA wykryje nadmiarowość w większym zakresie, będzie w stanie deduplikować twoje dane tutaj. Jest jednak wolniejszy niż Gzip.
Inną opcją jest 7-zip (
7z
wp7zip
pakiecie), który jest archiwizatorem (a nie kompresorem jedno-strumieniowym), który domyślnie korzysta z LZMA (napisany przez autora LZMA). Archiwizator 7-zip uruchamia własną deduplikację na poziomie pliku (patrząc na pliki z tym samym rozszerzeniem) podczas archiwizacji do swojego.7z
formatu. Oznacza to, że jeśli jesteś w stanie wymienićtar
z7z
, masz identyczne pliki deduplikacji. Jednak 7z nie zachowuje nanosekundowych znaczników czasu, uprawnień ani xattrów, więc może nie odpowiadać twoim potrzebom.lrzip
lrzip
to kompresor, który wstępnie przetwarza dane w celu usunięcia nadmiarowości na duże odległości przed przekazaniem ich do konwencjonalnego algorytmu, takiego jak Gzip / Deflate, bzip2, lzop lub LZMA. W przypadku podanych tutaj przykładowych danych nie jest to konieczne; przydaje się, gdy dane wejściowe są większe niż mogą zmieścić się w pamięci.W przypadku tego rodzaju danych (zduplikowane fragmenty nieściśliwe) należy zastosować
lzop
kompresję (bardzo szybko)lrzip
, ponieważ nie ma korzyści z trudniejszej kompresji całkowicie losowych danych po ich deduplikacji.Bup i Obnam
Ponieważ otagowałeś kopię zapasową pytania , jeśli Twoim celem jest tworzenie kopii zapasowej danych, rozważ użycie programu do tworzenia kopii zapasowych deduplikacji, takiego jak Bup lub Obnam .
źródło
W przypadku kopii zapasowej, prawdopodobnie z dużym zestawem mniejszych plików, jedną sztuczką, która może Ci pomóc, jest posortowanie plików w pliku tar według rozszerzenia:
źródło
rev
(dlaczego odwrócić, a potem posortować?) I spojrzę nasort
opcję „-r, --reverse” (choć nie jestem pewien, dlaczego miałbyś chcieć odwrócić). Ale myślę, że twojatar
opcja „-I
” nie robi tego, co myślisz, że „-I, --use-compress-program PROG
” , prawdopodobnie chcesz „-T, --files-from FILE”| tar czf my_archive.tar.gz -I -
powinno być| xargs tar Azf my_archive.tar.gz
rev
odwraca kolejność znaków w każdej linii, a nie kolejność linii w strumieniu. Z tego powodusort
grupuje pliki według ich rozszerzeń. Podejrzewam, że-I -
powinienem był-T -
, który zapewnia listę plików na stdin.rev
byłoby uporządkowane według rozszerzenia, nie że i tak jest wiele rozszerzeń w Linuksie. Wyobrażam sobie, że sortowanie według rozmiaru miałoby większą szansę na znalezienie dupgzip
nie znajdzie duplikatów, nawetxz
przy dużym rozmiarze słownika nie. Możesz użyćmksquashfs
- to rzeczywiście pozwoli zaoszczędzić miejsce na duplikaty.Kilka szybkich wyników badań z
xz
orazmksquashfs
z trzech przypadkowych plików binarnych (64MB), z których dwa są takie same:Ustawiać:
Squashfs:
xz:
źródło
Number of duplicate files found
w stdout.W moim systemie
lzma test.tar
powstaje plik test.tar.lzma o wielkości 106'3175 bajtów (1,1M)źródło
Jako dodatek do odpowiedzi „ślimaka mechanicznego”:
Nawet xz (lub lzma) nie znajdzie duplikatów, jeśli rozmiar nieskompresowanego pojedynczego pliku (lub, dokładniej, odległość między duplikatami) przekracza rozmiar słownika. xz (lub lzma) nawet przy najwyższych ustawieniach
-9e
rezerwuje na to tylko 64 MB.Na szczęście możesz określić swój własny rozmiar dyktafonu za pomocą opcji
--lzma2=dict=256MB
(--lzma1=dict=256MB
dozwolone tylko przy użyciu aliasu lzma do polecenia)Niestety, podczas nadpisywania ustawień niestandardowymi łańcuchami kompresji, jak podano w powyższym przykładzie, wartości domyślne dla wszystkich innych parametrów nie są ustawione na tym samym poziomie, co w przypadku -9e. Zatem gęstość kompresji nie jest tak wysoka dla pojedynczych plików.
źródło
gzip bez przełączników wiersza poleceń używa najniższego możliwego algorytmu kompresji.
Spróbuj użyć:
Powinieneś uzyskać lepsze wyniki
źródło