Kompresowanie wielu podobnych dużych plików

18

Mam setki podobnych dużych plików (po 30 megabajtów), które chcę skompresować. Każda para plików ma 99% tych samych danych (różnica mniejsza niż 1%), więc spodziewam się, że nie będę mieć więcej niż 40-50 megabajtów archiwum.

Pojedynczy plik może być skompresowany od 30 MB do 13-15 MB (z xz -1, gz -1, bzip2 -1), ale podczas kompresji dwa lub więcej plików Chcę mieć archiwum o wielkości 13-15MB + N*0.3MBgdzie N jest liczba plików.

Podczas używania tar(do tworzenia solidnego archiwum) i xz -6(do zdefiniowania słownika kompresji jako większego niż jeden plik - Aktualizacja - to nie wystarczyło! ), Nadal mam archiwum o rozmiarze N*13MB.

Myślę, że jedno gzipi drugie bzip2nie pomoże mi, ponieważ mają słownik mniejszy niż 1 MB, a mój strumień tar ma powtórzenia co 30 MB.

Jak mogę zarchiwizować mój problem we współczesnym systemie Linux przy użyciu standardowych narzędzi?

Czy można dostroić xzkompresję szybko, ale używać słownika większego niż 30–60 MB?

Aktualizacja : rozwiązał problem tar c input_directory | xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2G > compressed.tar.xz. Nie jestem pewien co do koniecznych opcji mf=hc4i --memory=2Gopcji; ale dict=128Mustaw słownik na wystarczająco duży (większy niż jeden plik) i mode=fastspraw, aby proces był nieco szybszy niż -e.

osgx
źródło
Uruchomienie xz -1 --memory=2Gnie pomogło, przetestowane na 2 i 4 plikach z zestawu.
osgx

Odpowiedzi:

12

Biorąc pod uwagę twoje dane, zakładam, że sprawdziłeś, że twoje pliki naprawdę mają 99% wspólnych danych, z ciągłym (lub prawie ciągłym) 1% różnicą między nimi.

Po pierwsze, powinieneś użyć tar, aby zrobić jedno archiwum z zawartymi w nim plikami. Na potrzeby testów utworzyłbym plik .tar z 10 plikami, a więc o rozmiarze 300 MB.

Następnie, używając xz, musisz ustawić go tak, aby słownik był większy niż rozmiar jednego pliku. Ponieważ nie mówisz, że masz ograniczenia pamięci, wybrałbym xz -9. Nie ma sensu nie wykorzystywać całej dostępnej pamięci.

Używałbym również ustawienia --extreme, aby sprawdzić, czy to robi różnicę.

Rozmiar słownika

W jednej dokumentacji, którą mam dostępną - na stronie - powiedziano, że rozmiar słownika jest mniej więcej równy zużyciu pamięci przez dekompresor. A parametr -1 oznacza dyktat 1MiB, -6 oznacza 10 MiB (lub 8 MiB w innej części tej samej instrukcji). Dlatego nie zyskujesz żadnej korzyści, tarując te pliki razem. Użycie -9 sprawiłoby, że dekompresor (a więc słownik) miałby 64 MiB i myślę, że tego właśnie chciałeś.

Edytować

Inną możliwością byłoby użycie innej sprężarki. Wybrałbym 7zip, ale najpierw spakowałem te pliki, a potem 7zip.

W zależności od zawartości plików, być może możesz użyć 7zip z metodą PPM-D (zamiast LZMA lub LZMA2, to jest domyślny i taki sam używany przez xz)

Nie dobrze: Zip (dict = 32kB), Bzip (dict = 900 kB).

woliveirajr
źródło
Zarówno Xz, jak i 7-Zip używają LZMA2, więc nie przyniosłoby to żadnych korzyści. PPMD jest zoptymalizowany do ekstremalnie powolnego, ale o wysokim stopniu kompresji wydobywania entropii z już skompresowanych mediów (np. MP3 i wideo). Nie jest szczególnie prawdopodobne znalezienie dużych podobieństw między tymi dwoma plikami i zapisanie ich w słowniku - nie bardziej niż LZMA2.
allquixotic
woliveirajr, co powiesz na użycie nie -1lub -9presetu, ale określ dict=64MBlub dict=128MBustaw mode=fast?
osgx
Użycie dict = xxMB zamiast -1 lub -9 przejdzie bezpośrednio do rzeczy, ale ponieważ nie wiem, jak xz ustawia inne parametry, gdy używasz tylko -9, nie wiem, czy czegoś nie przegapisz jeszcze. Myślę, że jesteś we właściwym kierunku, a samo testowanie da ci precyzyjną odpowiedź.
woliveirajr
3
Dzięki temu xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2Gbyłem w stanie skompresować 250 plików (7,5 GB) do 18 MB archiwum tar.xz.
osgx
@osgx :) to całkiem miłe. Jeśli nie zajęło to zbyt wiele czasu (tzn. Mieści się w twoich potrzebach), problem został rozwiązany! :) Więc masz final_size = 13 MB + x * 6kB, mniej więcej.
woliveirajr
9

Jeśli są one w 99% podobne, jak mówisz, powinieneś być w stanie użyć bsdiff lub podobnego algorytmu do obliczenia różnic między plikami. Czy różnica się kumuluje (tzn. Każdy plik różni się nieco bardziej od pierwszego), czy też różnica między dowolnymi dwoma plikami jest prawie taka sama?

Jeśli nie jest kumulatywny, powinieneś być w stanie:

  • Weź dowolny dowolny plik jako „linię bazową”
  • Biegać bsdiff porównanie pliku podstawowego z każdym dodatkowym plikiem
  • Przechowuj każdy plik różnicowy jako osobny plik obok pliku linii podstawowej
  • Uruchom kompresor jak xzw wynikach (linia bazowa + różnice).

Wynik powinien być znacznie mniejszy niż tylko xzcałe archiwum.

Następnie możesz „odtworzyć” oryginalne pliki, „nakładając” różnicę na linię bazową, aby usunąć każdy z pozostałych plików.

allquixotic
źródło
Nie kumuluje się. („Każda para plików ma 99% tych samych danych ...”)
osgx
1
Jeśli różnice nie kumulują się, powinno to być dobre zastosowanie bsdiffalgorytmu. Spróbuj.
allquixotic
Dziękuję za odpowiedź, ale już wykonałem zadanie z xz: tar c directory|xz --lzma2=dict=128M,mode=fasti usunąłem pliki wejściowe. Właściwie moje pliki wejściowe były tekstem, więc mogę nawet użyć diff zamiast bsdiff(który nie jest zainstalowany na moim komputerze).
osgx
5

Ty (I) możesz używać tar z jakimś archiwizatorem zdolnym do wykrywania wzorca dalekiego zasięgu, na przykład rzip lub lrzip ( Readme ). Oba używają detekcji / deduplikacji nadmiarowej dalekiego zasięgu, następnie rzip używa bzip2, a lrzip używa xz (lzma) / ZPAQ:

rzip to program do kompresji, podobny pod względem funkcjonalności do gzip lub bzip2, ale potrafiący korzystać z nadmiarowości na duże odległości w plikach, co może czasem pozwolić rzipowi na uzyskanie znacznie lepszych współczynników kompresji niż inne programy. ... Główną zaletą rzip jest to, że ma efektywny bufor historii o wielkości 900 MB. Oznacza to, że może znaleźć pasujące fragmenty pliku wejściowego na duże odległości w porównaniu do innych powszechnie używanych programów do kompresji. Dla porównania program gzip używa bufora historii o wielkości 32 kB, a bzip2 używa bufora historii o wielkości 900 kb

lrzip ma większy bufor i po deduplikacji może używać wielu algorytmów kompresji (bardzo szybko, szybko, dobrze i jeden z najlepszych - ZPAQ):

Lrzip korzysta z rozszerzonej wersji rzip, która redukuje nadmiarowość pierwszego przejścia na duże odległości. Dzięki modyfikacjom Lrzip skaluje się zgodnie z rozmiarem pamięci.

Dane są wtedy: 1. Kompresowane przez lzma (domyślnie), co zapewnia doskonałą kompresję przy około dwa razy większej prędkości kompresji bzip2 ...

Innym sposobem jest użycie bup - programu do tworzenia kopii zapasowych z deduplikacją na poziomie bloków / segmentów, opartego na pliku git:

Wykorzystuje algorytm kroczącej sumy kontrolnej (podobny do rsync) do dzielenia dużych plików na części.

osgx
źródło