Dlaczego przesyłanie strumieniowe „dd” przez gzip jest o wiele szybsze niż bezpośrednia kopia?

79

Chciałem wykonać kopię zapasową ścieżki z komputera w mojej sieci do innego komputera w tej samej sieci przez linię 100 Mbit / s. Zrobiłem to

dd if=/local/path of=/remote/path/in/local/network/backup.img

co dało mi bardzo niską prędkość przesyłu sieci około 50 do 100 kB / s, co zajęłoby wieczność. Więc go zatrzymałem i postanowiłem spróbować zgzipować go w locie, aby go znacznie zmniejszyć, aby kwota do transferu była mniejsza. Więc zrobiłem

dd if=/local/path | gzip > /remote/path/in/local/network/backup.img.gz

Ale teraz dostaję prędkość transferu sieci wynoszącą 1 MB / s, czyli 10 do 20 razy szybciej. Po zauważeniu tego przetestowałem to na kilku ścieżkach i plikach i zawsze było tak samo.

Dlaczego ddprzepuszczanie przez gziprurę również zwiększa szybkość przesyłania o duży czynnik, zamiast tylko zmniejszać długość strumienia o duży czynnik? Spodziewałem się nawet niewielkiego spadku szybkości transferu z powodu większego zużycia procesora podczas kompresji, ale teraz mam podwójny plus. Nie żebym nie był szczęśliwy, ale po prostu się zastanawiam. ;)

Bar Foo
źródło
1
512 bajtów było standardowym rozmiarem bloku do przechowywania plików we wczesnym Uniksie. Ponieważ w systemie Unix / Linux wszystko jest plikiem, stał się domyślnym plikiem dla prawie wszystkiego. Nowsze wersje większości narzędzi zwiększyły to, ale nie dd.
DocSalvager,
Prosta odpowiedź brzmi: ddwyjście z prędkością 1 MB / s ... bezpośrednio do oczekującej gziprury. Ma bardzo mało wspólnego z rozmiarem bloku.
Tullo_x86

Odpowiedzi:

100

dddomyślnie używa bardzo małego rozmiaru bloku - 512 bajtów (!!). To znaczy, wiele małych czyta i pisze. Wygląda na to dd, że naiwnie użyte w pierwszym przykładzie generowało dużą liczbę pakietów sieciowych o bardzo małej ładowności, zmniejszając w ten sposób przepustowość.

Z drugiej strony gzipjest wystarczająco inteligentny, aby wykonywać operacje wejścia / wyjścia z większymi buforami. Oznacza to, że mniejsza liczba dużych zapisów w sieci.

Czy możesz spróbować ddponownie z większym bs=parametrem i sprawdzić, czy tym razem działa lepiej?


źródło
20
Dzięki, wypróbowałem bezpośrednie kopiowanie bez gzip i blokowy rozmiar bs=10M-> szybki transfer sieciowy około 3 lub 4 MB / s. Większy rozmiar + gzipnie zmienił niczego w porównaniu do małego rozmiaru + gzip.
Foo Bar
7
Jeśli chcesz zobaczyć, jakie duże rozmiary bloków, spróbuj innego dd po gzip.
Joshua
Czy gzip robi własne buforowanie danych wyjściowych, czy po prostu używa stdio?
Barmar
@Barmar Jeśli poprawnie czytam źródło, to po prostu write(3)do bufora.
@CongMa możesz także spróbować użyć pigz zamiast gzip, będzie działać jeszcze szybciej
GioMac
4

Trochę za późno, ale czy mogę dodać ...

W wywiadzie zapytano mnie kiedyś, jaka byłaby najszybsza możliwa metoda klonowania danych bit-za-bit, a odpowiedzi zgrubne przy użyciu ddlub dc3dd( finansowane z DoD ). Wywiad potwierdził, że rurociąg ddna ddbardziej wydajne, jak to po prostu pozwala na jednoczesny odczyt / zapis lub w warunkach programista stdin/stdout, więc ultimatly podwojenie szybkości zapisu i czas transferu Halfing.

dc3dd verb=on if=/media/backup.img | dc3dd of=/dev/sdb
Sadik Tekin
źródło
1
Nie sądzę, że to prawda. Właśnie próbowałem teraz. dd status=progress if=/dev/zero count=100000 bs=1M of=/dev/nullbyło 22,5 GB / s, dd status=progress if=/dev/zero count=100000 bs=1M | dd of=/dev/null bs=1Mbyło 2,7 GB. Więc rura spowalnia.
falsePockets
0

Cong ma rację. Przesyłasz strumieniowo bloki z dysku nieskompresowanego na zdalny host. Interfejs sieciowy, sieć i zdalny serwer są ograniczeniami. Najpierw musisz zwiększyć wydajność DD. Określenie parametru bs =, który będzie wyrównany z pamięcią bufora dysków, zapewni największą wydajność z dysku. Powiedz na przykład bs = 32 mln. Spowoduje to wypełnienie bufora gzip przy cieśninie SATA lub SAS Line Rate z bufora napędów. Dysk będzie bardziej skłonny do sekwencyjnego transferu, co zapewni lepsze przekazywanie. Gzip skompresuje dane w strumieniu i wyśle ​​je do Twojej lokalizacji. Jeśli używasz NFS, który pozwoli na minimalną transmisję NFS. Jeśli korzystasz z SSH, ponosisz enkapsulację i narzut szyfrowania SSH. Jeśli używasz netcata, nie masz szyfrowania nad głową.

Robert
źródło
0

Zakładam tutaj, że zgłaszana jest „prędkość transferu”, o której mowa dd. To naprawdę ma sens, ponieważ w ddrzeczywistości przesyła 10 razy więcej danych na sekundę ! Nie ddprzenosi się jednak przez sieć - gzipproces ten jest obsługiwany przez proces.

Trochę kontekstu: gzipzużywa dane z potoku wejściowego tak szybko, jak może wyczyścić bufor wewnętrzny. Szybkość gzipopróżniania bufora zależy od kilku czynników:

  • Przepustowość zapisu we / wy (która jest wąska dla sieci i pozostaje stała)
  • Przepustowość odczytu we / wy (która będzie znacznie wyższa niż 1 MB / s odczytu z dysku lokalnego na nowoczesnej maszynie, dlatego nie jest prawdopodobne wąskie gardło)
  • Jego współczynnik kompresji (który zakładam, że przy 10-krotnym przyspieszeniu wynosi około 10%, co wskazuje, że kompresujesz jakiś bardzo powtarzalny tekst, taki jak plik dziennika lub jakiś XML)

Tak więc w tym przypadku sieć może obsłużyć 100 kB / s i gzipkompresuje dane około 10: 1 (i nie jest wąskie gardło procesora). Oznacza to, że podczas gdy generuje 100 kB / s, gzipmoże zużywać 1 MB / s, a tempo zużycia jest ddwidoczne.

Tullo_x86
źródło