bzip2 jest zbyt wolny. Dostępnych jest wiele rdzeni


31

Uruchamiam to polecenie:

pg_dumpall | bzip2 > cluster-$(date --iso).sql.bz2

To trwa zbyt długo. Patrzę na procesy z top. Proces bzip2 zajmuje około 95%, a postgres 5% jednego rdzenia. waWpis jest niska. Oznacza to, że dysk nie stanowi wąskiego gardła.

Co mogę zrobić, aby zwiększyć wydajność?

Może niech bzip2 użyje więcej rdzeni. Serwery mają 16 rdzeni.

Lub użyj alternatywy dla bzip2?

Co mogę zrobić, aby zwiększyć wydajność?


8
O ile nie potrzebujesz bzip2 z wcześniejszych powodów, moim osobistym doświadczeniem było to, że xz zapewnia lepszą kompresję / czas niż bzip2. Jest także wątkowy, jeśli masz wystarczająco nowy program, i pozwala skalować czas i zużycie pamięci od gzipish do ogromnych, w zależności od tego, czego chcesz.
Perkins,

6
„pigz” to kolejna opcja - tworzy wyjście gzip zamiast wyjścia bzip2. I w zasadzie wszystko rozumie gzip.
Criggie

Możesz spróbować zaszyfrować go symetrycznie za pomocą GnuPG z kompresją bzip2; wydaje się zaskakująco szybki w porównaniu z samą kompresją, z nieznanego powodu, nawet przy najwyższym poziomie kompresji. Możliwe, że algorytm może być szybszy niż wydajność mojego regularnego programu do kompresji, który jest oparty na GUI.
Shule

2
Nie określiłeś wymagań swojego alternatywnego algorytmu. Bzip2 można podzielić. Czy to dla ciebie ważne?
Martin Smith,

7
Co mogę zrobić, aby zwiększyć wydajność? ” - nie kompresować? W rzeczywistości nie mówisz, że potrzebujesz go skompresowanego, a nie wykonywanie pracy jest zawsze szybsze niż wykonywanie pracy. Uczyń dysk wąskim gardłem.
TessellatingHeckler

Odpowiedzi:


49

Istnieje wiele algorytmów kompresji i bzip2jest to jeden z tych wolniejszych. Zwykły jest gzipzwykle znacznie szybszy, przy zwykle niewiele gorszej kompresji. Kiedy prędkość jest najważniejsza, lzopjest moim ulubionym. Słaba kompresja, ale och, tak szybko.

Postanowiłem się zabawić i porównać kilka algorytmów, w tym ich równoległe implementacje. Plik wejściowy jest wynikiem pg_dumpallpolecenia na mojej stacji roboczej, pliku SQL 1913 MB. Sprzęt to starszy czterordzeniowy i5. Czasy są zegarem ściennym samego kompresji. Równoległe implementacje są ustawione na wykorzystanie wszystkich 4 rdzeni. Tabela posortowana według prędkości kompresji.

Algorithm     Compressed size        Compression          Decompression

lzop           398MB    20.8%      4.2s    455.6MB/s     3.1s    617.3MB/s
lz4            416MB    21.7%      4.5s    424.2MB/s     1.6s   1181.3MB/s
brotli (q0)    307MB    16.1%      7.3s    262.1MB/s     4.9s    390.5MB/s
brotli (q1)    234MB    12.2%      8.7s    220.0MB/s     4.9s    390.5MB/s
zstd           266MB    13.9%     11.9s    161.1MB/s     3.5s    539.5MB/s
pigz (x4)      232MB    12.1%     13.1s    146.1MB/s     4.2s    455.6MB/s
gzip           232MB    12.1%     39.1s     48.9MB/s     9.2s    208.0MB/s
lbzip2 (x4)    188MB     9.9%     42.0s     45.6MB/s    13.2s    144.9MB/s
pbzip2 (x4)    189MB     9.9%    117.5s     16.3MB/s    20.1s     95.2MB/s
bzip2          189MB     9.9%    273.4s      7.0MB/s    42.8s     44.7MB/s
pixz (x4)      132MB     6.9%    456.3s      4.2MB/s     7.9s    242.2MB/s
xz             132MB     6.9%   1027.8s      1.9MB/s    17.3s    110.6MB/s
brotli (q11)   141MB     7.4%   4979.2s      0.4MB/s     3.6s    531.6MB/s

Jeśli 16 rdzeni twojego serwera jest na tyle bezczynnych, że wszystkie mogą być użyte do kompresji, pbzip2prawdopodobnie zapewnią ci bardzo znaczne przyspieszenie. Ale wciąż potrzebujesz większej prędkości i możesz tolerować ~ 20% większe pliki, gzipto prawdopodobnie najlepszy wybór.

Aktualizacja: Dodałem brotli(patrz odpowiedź TOOGAM) wyniki do tabeli. brotlis ustawienie jakości kompresji ma bardzo duży wpływ na współczynnik kompresji i prędkości, więc dodałam trzy ustawienia ( q0, q1, i q11). Domyślnie jest q11, ale jest bardzo powolny i wciąż gorzej niż xz. q1wygląda jednak bardzo dobrze; taki sam współczynnik kompresji jak gzip, ale 4-5 razy szybszy!

Aktualizacja: Dodano lbzip2(patrz komentarz gmathts) i zstd(komentarz Johnny'ego) do tabeli i posortowano według szybkości kompresji. lbzip2stawia bzip2powrót rodziny w prowadzeniu przez kompresję trzy razy tak szybko, jak pbzip2z wielkim stopniu sprężania! zstdrównież wygląda rozsądnie, ale pokonuje go brotli (q1)zarówno stosunek, jak i prędkość.

Mój oryginalny wniosek, że zwykły gzipjest najlepszym zakładem, zaczyna wyglądać niemal głupio. Choć dla wszechobecności wciąż nie da się go pokonać;)


1
Na podobny-owski tabeli z dużo większą algorytmów, zobacz mattmahoney.net/dc/text.html .
Dougal

1
@Dougal Fair dosyć. Mój test dotyczy jednak podobnych danych jak OP ( pg_dumpalldane wyjściowe), więc prawdopodobnie jest nieco bardziej reprezentatywny :)
marcelm

1
Zstd jest kolejnym, którego brakuje w tabeli - do kompresji naszych plików dziennika odkryłem, że pojedynczy proces Zstd przewyższa 16 rdzeni pbzip2 przy porównywalnych współczynnikach kompresji.
Johnny,

1
lz4przy okazji, jest nieco szybszy i wydajniejszy niż lzop. Zużywa jednak więcej pamięci RAM, co jest istotne w systemach wbudowanych.
Daniel B

1
Jeśli chcesz przetestować wersje wielowątkowe, możesz też spróbować zstd -T4. Aby uzyskać bardzo szybkie ustawienia, możesz spróbować zstd -T4 -1, zstddomyślnie -3, prawdopodobnie testowane ustawienie.
Cyan

37

Użyj pbzip2.

Instrukcja mówi:

pbzip2 jest równoległą implementacją kompresora plików bzip2 sortującego bloki, który wykorzystuje pthreads i osiąga prawie liniowe przyspieszenie na maszynach SMP. Dane wyjściowe tej wersji są w pełni zgodne z wersją bzip2 v1.0.2 lub nowszą (tzn. Wszystko skompresowane za pomocą pbzip2 można zdekompresować za pomocą bzip2).

Automatycznie wykrywa liczbę posiadanych procesorów i odpowiednio tworzy wątki.


To dobrze, jeśli kompresujesz plik, działa to jednak okropnie przez potok
camelccc

@camelccc Dlaczego tak mówisz? W ogóle nie uważam, że tak jest. Potrzebujesz szybkiego producenta lub dużego bufora na rurze przed nim, aby uzyskać optymalną wydajność, ale to samo dotyczy pixzi pigzna rurze.
Michael - sqlbot

Zależy, jak duże jest to, co kompresuje. Jeśli masz duży bufor, wszystko jest w porządku, jak mówisz, jeśli przesyłasz coś znacznie większego niż fizyczny taran, zauważyłem, że rzeczy mogą stać się bardziej interesujące. Jednak, jak mówisz, prawdopodobnie jest to prawda dla dowolnego algorytmu kompresji.
camelccc

4
bzip2 może używać sporo pamięci RAM, więc uruchamianie 16 pracowników bzip jednocześnie może zużywać nietrywialny pamięci RAM, ponad 1 GB. BTW, lbzip2wydaje się dawać lepszą prędkość, zużycie pamięci i nieznacznie lepszą kompresję niż pbzip2. Tutaj są testy: vbtechsupport.com/1614
gmatht

@gmatht lbzip2wygląda ładnie! Dodałem go do mojej odpowiedzi :)
marcelm,

8

Nie wspominałeś o systemie operacyjnym. Jeśli Windows, 7-Zip ze ZStandardem (wersje) to wersja 7-Zip, która została zmodyfikowana w celu zapewnienia obsługi wszystkich tych algorytmów.


Interesujące, o czym słyszałem brotliwcześniej, ale o tym zapomniałem. W odpowiedzi dodałem go do tabeli wskaźników! Byłem trochę rozczarowany jego wydajnością, z wyjątkiem ustawienia jakości 1, w którym zapewniał ten sam współczynnik kompresji, co gzipprzy znacznie wyższej prędkości.
marcelm

2

Użyj ZSTD . Jeśli jest wystarczająco dobry dla Facebooka, prawdopodobnie jest również wystarczająco dobry dla ciebie.

Mówiąc poważniej, jest całkiem niezły . Teraz używam go do wszystkiego, ponieważ po prostu działa i pozwala handlować prędkością na współczynnik na dużą skalę (najczęściej i tak prędkość ma większe znaczenie niż rozmiar, ponieważ przechowywanie jest tanie, ale prędkość jest wąskim gardłem).
Przy poziomach kompresji, które osiągają porównywalną ogólną kompresję jak bzip2, jest to znacznie szybsze, a jeśli chcesz zapłacić trochę więcej czasu procesora, możesz prawie osiągnąć wyniki podobne do LZMA (chociaż wtedy będzie wolniejsze niż bzip2). Przy nieco gorszych współczynnikach kompresji jest znacznie szybszy niż bzip2 lub jakakolwiek inna alternatywa głównego nurtu.

Teraz kompresujesz zrzut SQL, który jest tak żenująco trywialny, jak to tylko możliwe. Nawet najbiedniejsze kompresory osiągają dobre wyniki na tego rodzaju danych.
Możesz więc działać zstdz niższym poziomem kompresji, który będzie działał dziesiątki razy szybciej i nadal osiąga 95-99% tej samej kompresji dla tych danych.

Jako bonus, jeśli będziesz to robił często i chcesz zainwestować trochę więcej czasu, możesz „trenować” zstdsprężarkę przed czasem, co zwiększa zarówno współczynnik sprężania, jak i prędkość. Pamiętaj, że aby trening działał dobrze, musisz podać mu indywidualne rekordy, a nie całość. Sposób działania narzędzia wymaga treningu wielu małych i nieco podobnych próbek, a nie jednej dużej kropli.


jeszcze lepiej, użyj pzstd (wersja równoległa) na maszynach wielordzeniowych
borowis,

1

Wygląda na to, że dostosowanie (obniżenie) rozmiaru bloku może mieć znaczący wpływ na czas kompresji.

Oto niektóre wyniki eksperymentu przeprowadzonego na mojej maszynie. Użyłem timepolecenia do pomiaru czasu wykonania. input.txtto plik tekstowy o wielkości ~ 250 MB zawierający dowolne rekordy JSON.

Używanie domyślnego (największego) rozmiaru bloku ( --bestjedynie wybiera domyślne zachowanie):

# time cat input.txt | bzip2 --best > input-compressed-best.txt.bz

real    0m48.918s
user    0m48.397s
sys     0m0.767s

Używając najmniejszego rozmiaru bloku ( --fastargument):

# time cat input.txt | bzip2 --fast > input-compressed-fast.txt.bz

real    0m33.859s
user    0m33.571s
sys     0m0.741s

Było to nieco zaskakujące odkrycie, biorąc pod uwagę, że dokumentacja mówi:

Rozmiar bloku nie ma wpływu na szybkość kompresji i dekompresji


Mój obecny faworyt to pbzip2. Też tego próbowałeś? To pytanie dotyczy środowiska, w którym dostępnych jest 16 rdzeni.
guettli

@ guettli niestety muszę się trzymać bzipa. Używam go do zadań Hadoop, a bzip jest jedną z wbudowanych kompresji. W pewnym sensie jest to już sparaliżowane.
Jakub Kukul
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.