Czas skompresować bardzo duże pliki (100G)

27

Muszę skompresować wiele bardzo dużych plików (80-GB GB) i jestem zaskoczony (brakiem) szybkości, jaką wykazuje mój system. Mam szybkość konwersji około 500 MB / min; za pomocą top, wydaje mi się, że używam jednego procesora na około 100%.

Jestem pewien, że nie jest to (tylko) prędkość dostępu do dysku, ponieważ utworzenie tarpliku (tak powstał plik 80G) zajęło tylko kilka minut (może 5 lub 10), ale po ponad 2 godzinach moja prosta komenda gzip jest nadal nie skończone.

W podsumowaniu:

tar -cvf myStuff.tar myDir/*

Zajęło mniej niż 5 minut, aby utworzyć plik o wielkości 87 G

gzip myStuff.tar

Zajęło dwie godziny i 10 minut, tworząc plik zip 55G.

Moje pytanie: czy to normalne? Czy istnieją pewne opcje gzipprzyspieszenia? Czy szybsze byłoby łączenie poleceń i używanie tar -cvfz? Widziałem odniesienie do pigz- Równoległej implementacji GZip - ale niestety nie mogę zainstalować oprogramowania na komputerze, którego używam, więc nie jest to dla mnie opcja. Zobacz na przykład to wcześniejsze pytanie .

Zamierzam sam wypróbować niektóre z tych opcji i zmierzyć czas - ale jest całkiem prawdopodobne, że nie trafię w „magiczną kombinację” opcji. Mam nadzieję, że ktoś na tej stronie zna właściwą sztuczkę, aby przyspieszyć.

Kiedy będę mieć wyniki innych prób, zaktualizuję to pytanie - ale jeśli ktoś ma szczególnie dobrą sztuczkę, byłbym bardzo wdzięczny. Może gzip zajmuje tylko więcej czasu niż sobie uświadomiłem ...

AKTUALIZACJA

Zgodnie z obietnicą wypróbowałem poniższe sztuczki: zmień stopień kompresji i zmień miejsce docelowe pliku. Otrzymałem następujące wyniki dla tar, który miał około 4,1 GB:

flag    user      system   size    sameDisk
-1     189.77s    13.64s  2.786G     +7.2s 
-2     197.20s    12.88s  2.776G     +3.4s
-3     207.03s    10.49s  2.739G     +1.2s
-4     223.28s    13.73s  2.735G     +0.9s
-5     237.79s     9.28s  2.704G     -0.4s
-6     271.69s    14.56s  2.700G     +1.4s
-7     307.70s    10.97s  2.699G     +0.9s
-8     528.66s    10.51s  2.698G     -6.3s
-9     722.61s    12.24s  2.698G     -4.0s

Tak więc, zmiana flagi z domyślnej -6na najszybszą -1daje mi 30% przyspieszenie, przy (dla moich danych) prawie żadnej zmianie rozmiaru pliku zip. To, czy używam tego samego dysku, czy innego, nie ma w zasadzie żadnej różnicy (musiałbym uruchomić to wiele razy, aby uzyskać jakiekolwiek znaczenie statystyczne).

Jeśli ktoś jest zainteresowany, wygenerowałem te testy czasowe przy użyciu następujących dwóch skryptów:

#!/bin/bash
# compare compression speeds with different options
sameDisk='./'
otherDisk='/tmp/'
sourceDir='/dirToCompress'
logFile='./timerOutput'
rm $logFile

for i in {1..9}
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $sameDisk $logFile
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $otherDisk $logFile
done

I drugi skrypt ( compressWith):

#!/bin/bash
# use: compressWith sourceDir compressionFlag destinationDisk logFile
echo "compressing $1 to $3 with setting $2" >> $4
tar -c $1 | gzip -$2 > $3test-$2.tar.gz

Trzy rzeczy do zapamiętania:

  1. Używanie /usr/bin/timezamiast time, ponieważ wbudowane polecenie programu bashma o wiele mniej opcji niż polecenie GNU
  2. Nie zawracałem sobie głowy korzystaniem z tej --formatopcji, chociaż to ułatwiłoby odczytanie pliku dziennika
  3. Użyłem skryptu w skrypcie, ponieważ timewydawało się, że działa tylko na pierwszym poleceniu w sekwencji potokowej (więc sprawiłem, że wyglądało to jak jedno polecenie ...).

Po tym wszystkim, moje wnioski są

  1. Przyspiesz z -1flagą (zaakceptowana odpowiedź)
  2. Znacznie więcej czasu zajmuje kompresja danych niż odczyt z dysku
  3. Zainwestuj w szybsze oprogramowanie do kompresji ( pigzwydaje się dobrym wyborem).
  4. Jeśli masz wiele plików do kompresji, możesz umieścić każde gzippolecenie w osobnym wątku i użyć więcej dostępnego procesora (biednego człowieka pigz)

Dziękujemy wszystkim, którzy pomogli mi się tego wszystkiego nauczyć!

Floris
źródło
tar -cvf nie kompresuje, więc będzie szybszy
parkydr
2
@Floris: jakie dane próbujesz skompresować? uwaga dodatkowa: $> gzip -c myStuff.tar | pv -r -b > myStuff.tar.gzpokaże, jak szybko twoja maszyna kompresuje rzeczy. uwaga dodatkowa 2: zapisz wynik na innej płycie.
akira
3
Przepraszam, źle odczytałem twoje pytanie. gzip ma opcję --fast, aby wybrać najszybszą kompresję
parkydr
1
@parkydr: Opcja --fast to taka, o której nie wiedziałam ... jest to ostatnia na manstronie i nie przeczytałam aż tak daleko (ponieważ jest posortowana według „polecenia jednoliterowego”, czyli -#) . To nauczy mnie RTFM! To będzie następna rzecz, której spróbuję!
Floris
2
Zauważ, że jeśli na komputerze dostępny jest odpowiedni kompilator, a uprawnienia systemu plików nie są ustawione tak, aby zabraniać wykonywania plików binarnych z katalogów, do których masz dostęp, możesz go skompilować pigzi uruchomić z dowolnego miejsca, w którym go zbudowałeś, bez instalowania go. Jeśli nie ma kompilatora, możesz go skompilować krzyżowo na innym komputerze, chociaż zaczyna to być trudniejsze niż być tego warte. (Myślę, że w zależności od tego, jak bardzo potrzebujesz tej kompresji, aby działała szybciej.)
David Z

Odpowiedzi:

27

Możesz zmienić prędkość gzip za pomocą --fast --bestlub, -#gdzie # to liczba od 1 do 9 (1 to najszybsza, ale mniejsza kompresja, 9 to najwolniejsza, ale większa kompresja). Domyślnie gzip działa na poziomie 6.

robingrindrod
źródło
26

Powodem, dla którego tar zajmuje tak mało czasu w porównaniu do gzip, jest to, że kopiowanie plików do jednego pliku jest bardzo niewielkie (co jest tym, co robi). Z drugiej strony gzip używa algorytmów kompresji do zmniejszenia pliku tar.

Problem polega na tym, że gzip jest ograniczony (jak odkryłeś) do jednego wątku.

Wpisz pigz , który może używać wielu wątków do wykonania kompresji. Przykładem tego może być:

tar -c --use-compress-program=pigz -f tar.file dir_to_zip

Na stronie siostrzanej znajduje się ładne podsumowanie w skrócie opcji --use-compress-program .

Steve Gore
źródło
Dziękujemy za odpowiedź i linki. Właściwie wspomniałem o pigz w pytaniu.
Floris
To jest poprawna odpowiedź tutaj ..!
stolsvik
4

Wydaje mi się, że używam jednego procesora na około 100%.

Oznacza to, że nie występuje problem z wydajnością We / Wy, ale kompresja wykorzystuje tylko jeden wątek (tak będzie w przypadku gzip).

Jeśli uda ci się uzyskać dostęp / zgodę potrzebną do zainstalowania innych narzędzi, 7zip obsługuje również wiele wątków, aby skorzystać z wielordzeniowych procesorów, chociaż nie jestem pewien, czy dotyczy to zarówno formatu gzip, jak i własnego.

Jeśli na razie nie możesz użyć tylko gzip i masz wiele plików do kompresji, możesz spróbować skompresować je osobno - w ten sposób wykorzystasz więcej tego wielordzeniowego procesora, uruchamiając więcej niż jeden proces równolegle. Uważaj jednak, aby nie przesadzić, ponieważ gdy tylko zbliżysz się do wydajności podsystemu we / wy, wydajność spadnie gwałtownie (do mniej niż w przypadku korzystania z jednego procesu / wątku), ponieważ opóźnienie ruchów głowy staje się znaczące szyjka.

David Spillett
źródło
Dzięki za wkład. Dałeś mi pomysł (na który dostajesz opinię): ponieważ mam wiele archiwów do stworzenia, mogę po prostu napisać poszczególne polecenia, a &następnie - a następnie pozwolić systemowi zająć się tym stamtąd. Każdy z nich będzie działał na swoim własnym procesorze, a ponieważ poświęcam znacznie więcej czasu na kompresję niż na We / Wy, zrobienie jednego zajmie tyle samo, co wszystkich 10 z nich. Dostaję więc „wydajność wielu rdzeni” z pliku wykonywalnego, który jest jednowątkowy ...
Floris
1

Można również wykorzystać liczbę dostępnych procesów w pigz, co zwykle oznacza wyższą wydajność, jak pokazano w poniższym poleceniu

tar cf - katalog do archiwizacji | pigz -0 -p numer_większości> mydir.tar.gz

Przykład - tar cf - patha | pigz -0 -p 32> patha.tar.gz

Jest to prawdopodobnie szybsze niż metody sugerowane w poście, ponieważ -p to liczba procesów, które można uruchomić. Z mojego osobistego doświadczenia ustawienie bardzo dużej wartości nie wpływa negatywnie na wydajność, jeśli katalog do archiwizacji składa się z dużej liczby małych plików. W przeciwnym razie rozważana wartość domyślna to 8. W przypadku dużych plików zalecam ustawienie tej wartości jako całkowitej liczby wątków obsługiwanych w systemie.

Przykład pomaga ustawienie wartości p = 32 w przypadku maszyny z 32 procesorami.

0 oznacza najszybszą kompresję Pigza, ponieważ nie kompresuje archiwum, a raczej koncentruje się na szybkości. Wartość domyślna to 6 dla kompresji.

Ankit Shah
źródło