Pourquoi la tuyauterie 'dd' à travers gzip est-elle tellement plus rapide qu'une copie directe?

79

Je voulais sauvegarder un chemin d'un ordinateur de mon réseau vers un autre ordinateur du même réseau sur une ligne à 100 Mbit / s. Pour cela j'ai fait

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

ce qui m'a donné une vitesse de transfert réseau très faible d'environ 50 à 100 ko / s, ce qui aurait pris une éternité. Alors je l'ai arrêté et j'ai décidé d'essayer de le gzipper à la volée pour le rendre beaucoup plus petit afin que le montant à transférer soit inférieur. Alors j'ai fait

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

Mais maintenant, je reçois quelque chose comme une vitesse de transfert réseau de 1 Mo / s, soit un facteur de 10 à 20 fois plus rapide. Après avoir remarqué cela, je l'ai testé sur plusieurs chemins et fichiers, et c'était toujours le même.

Pourquoi ne tuyauterie à ddtravers gzipégalement d' augmenter les taux de transfert par un facteur au lieu de réduire uniquement le ByteLength du flux par un facteur important? Je m'attendais même à une légère diminution des taux de transfert, en raison de la consommation plus élevée de la part du processeur lors de la compression, mais je reçois maintenant un double plus. Non pas que je ne sois pas heureux, mais je me pose une question. ;)

Foo Bar
la source
1
512 octets était la taille de bloc standard pour le stockage de fichiers au début de Unix. Comme tout est un fichier sous Unix / Linux, il est devenu le fichier par défaut pour à peu près tout. Les versions les plus récentes de la plupart des utilitaires ont augmenté cela, mais pas dd.
DocSalvager
La réponse simple est que la ddsortie à 1 Mo / s ... directement dans le gziptuyau en attente . Cela a très peu à voir avec la taille des blocs.
Tullo_x86

Réponses:

100

ddutilise par défaut une très petite taille de bloc - 512 octets (!!). C'est-à-dire beaucoup de petites lectures et écritures. Il semble que dd, utilisé naïvement dans votre premier exemple, générait un grand nombre de paquets réseau avec une charge utile très réduite, réduisant ainsi le débit.

D'autre part, gzipest assez intelligent pour faire des E / S avec des tampons plus grands. C'est-à-dire qu'un plus petit nombre de grosses écritures sur le réseau.

Pouvez-vous essayer à ddnouveau avec un bs=paramètre plus grand et voir si cela fonctionne mieux cette fois-ci?


la source
20
Merci, essayé de copie directe sans gzip et une taille de bloc de bs=10M-> transfert réseau rapide de quelque chose à propos de 3 ou 4 Mo / s. Une taille de bloc supérieure + gzipn'a rien changé par rapport à une petite taille de bloc + gzip.
Foo Bar
7
Si vous voulez voir quelles tailles de blocs sont élevées, essayez un autre jour après le gzip.
Josué
Est-ce que gzip utilise sa propre mise en tampon de sortie, ou utilise-t-il simplement stdio?
Barmar
@Barmar Si je lis correctement la source, c’est tout simplement write(3)dans la mémoire tampon.
@CongMa, vous pouvez aussi essayer d'utiliser pigz au lieu de gzip, cela fonctionnera encore plus vite
GioMac le
4

Peu en retard à cela, mais pourrais-je ajouter ...

Lors d’un entretien, on m’a demandé une fois quelle serait la méthode la plus rapide possible pour cloner des données bit à bit et les réponses brutes avec l’utilisation de ddou dc3dd( financé par le DoD ). L'intervieweur a confirmé que la tuyauterie ddà ddest plus efficace, car elle permet simplement la lecture / écriture simultanée ou en termes de programmation stdin/stdout, doublant ainsi ultimement les vitesses d'écriture et le temps de transfert de moitié.

dc3dd verb=on if=/media/backup.img | dc3dd of=/dev/sdb
Sadik Tekin
la source
1
Je ne pense pas que ce soit vrai. Je viens d'essayer maintenant. dd status=progress if=/dev/zero count=100000 bs=1M of=/dev/nullétait de 22,5 Go / s, dd status=progress if=/dev/zero count=100000 bs=1M | dd of=/dev/null bs=1Métait de 2,7 Go. Donc, le tuyau le ralentit.
falsePockets
0

Cong est correct. Vous diffusez les blocs hors du disque non compressé vers un hôte distant. Votre interface réseau, votre réseau et votre serveur distant sont la limitation. Vous devez d’abord améliorer les performances de DD. Spécifier un paramètre bs = qui s'aligne sur la mémoire tampon des disques optimisera les performances du disque. Dites bs = 32M par exemple. Ceci remplira alors le tampon de gzip au niveau de sata ou de sas dans le lecteur. Le disque sera plus enclin à un transfert séquentiel donnant de meilleurs résultats. Gzip va compresser les données en flux et les envoyer à votre emplacement. Si vous utilisez NFS, cela permettra à la transmission nfs d’être minime. Si vous utilisez SSH, vous encresz la surcharge d'encapsulation et de cryptage SSH. Si vous utilisez netcat, vous n'avez aucun cryptage sur la tête.

Robert
la source
0

Je suppose ici que la "vitesse de transfert" à laquelle vous faites référence est rapportée dd. Cela a du sens, car nous ddtransférons 10 fois plus de données par seconde ! Cependant, le ddtransfert n’est pas effectué sur le réseau - ce travail est traité par le gzipprocessus.

Certains contextes: gzipconsommeront les données de son canal d’entrée aussi vite que possible pour effacer son tampon interne. La vitesse à laquelle gziple tampon se vide dépend de plusieurs facteurs:

  • La bande passante d’écriture des E / S (goulet d’étranglement par le réseau et est restée constante)
  • La bande passante de lecture des E / S (qui sera bien supérieure à 1 Mo / s en lecture à partir d'un disque local sur une machine moderne, ne constitue donc pas un goulot d'étranglement)
  • Son taux de compression (ce que je suppose, d'après votre accélération 10x, autour de 10%, ce qui indique que vous compressez un texte très répétitif tel qu'un fichier journal ou un fichier XML)

Donc, dans ce cas, le réseau peut gérer 100 ko / s et gzipcompresse les données autour de 10: 1 (et il n’est pas gêné par le processeur). Cela signifie que pendant qu'il produit 100 Ko / s, il gzippeut consommer 1 Mo / s, et le taux de consommation est ce que l' ddon peut voir.

Tullo_x86
la source