なぜ直接「dd」をgzipにパイプするのは、直接コピーよりもずっと速いのですか?


79

ネットワーク内のコンピューターから同じネットワーク内の別のコンピューターへのパスを100 Mbit / s回線でバックアップしたかった。このために私はやった

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

これにより、ネットワーク転送速度が非常に低くなり、約50〜100 kB / sになりました。これは永遠にかかっていたはずです。そこで、私はそれを止めて、その場でgzip圧縮して、転送量が少なくなるように、はるかに小さくすることにしました。だから私はやった

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

しかし、今では1 MB /秒のネットワーク転送速度のようなものが得られるため、10〜20倍速くなります。これに気づいた後、いくつかのパスとファイルでこれをテストしましたが、常に同じでした。

パイプddスルーgzipは、ストリームのバイト長を大幅に削減するのではなく、転送率を大幅に向上させるのはなぜですか?圧縮中のCPU消費量が増加するため、代わりに転送レートがわずかに低下することも予想されていましたが、今ではダブルプラスになります。私は幸せではないというわけではありませんが、私はただ疑問に思っています。;)


1
512バイトは、初期のUnixのファイルストレージの標準ブロックサイズでした。すべてがUnix / Linuxのファイルであるため、ほぼすべてのデフォルトになりました。ほとんどのユーティリティの新しいバージョンでは、ddでなく増加しています。
DocSalvager 14年

簡単な答えは、dd1MB /秒で出力することです...待機gzipパイプに直接出力されます。ブロックサイズとはほとんど関係ありません。
Tullo_x86

回答:


100

ddデフォルトでは、512バイト(!!)という非常に小さなブロックサイズを使用します。つまり、多くの小さな読み取りと書き込み。と思われdd、このようにスループットが低下、非常に小さなペイロードとネットワークパケットの偉大な数を生成して、あなたの最初の例では単純に使用され、。

一方、gzipより大きなバッファでI / Oを実行するのに十分スマートです。つまり、ネットワークを介した少数の大きな書き込み。

ddより大きなbs=パラメーターでもう一度試してみて、今度はそれがうまく機能するかどうかを確認できますか?


20
おかげで、ブロックサイズなし gzipで直接コピー試みましたbs=10M-> 3または4 MB / sの何かの高速ネットワーク転送。大きいブロックサイズ+ gzipは、小さいブロックサイズ+と比較して何も変わりませんでしたgzip
フーバー

7
高いブロックサイズを確認するには、gzipの後に別のddを試してください。
ジョシュア

gzipは独自の出力バッファリングを行っていますか、それともstdioのみを使用していますか?
バーマー

@Barmarソースを正しく読んでいる場合、単純write(3)にバッファに送られます。

@CongMa gzipの代わりにpigzを試して使用することもできます。これはさらに高速に動作します
-GioMac

4

これに少し遅れましたが、私は追加するかもしれません...

インタビューで、ビット単位のデータをクローンするための可能な限り迅速な方法どれかと尋ねられ、ddor dc3ddDoD Funded)を使用して大まかに応答しました。インタビュアーは、パイピングがより効率的であるddことを確認しddました。これにより、同時読み取り/書き込みまたはプログラマー用語stdin/stdoutで単純に許可れるため、書き込み速度が2倍になり、転送時間が半分になります。

dc3dd verb=on if=/media/backup.img | dc3dd of=/dev/sdb

1
私はそれが本当だとは思わない。今すぐ試しました。dd status=progress if=/dev/zero count=100000 bs=1M of=/dev/null22.5GB /秒、dd status=progress if=/dev/zero count=100000 bs=1M | dd of=/dev/null bs=1M2.7GBでした。そのため、パイプが遅くなります。
falsePockets

0

コングは正しいです。圧縮されていないディスクからブロックをリモートホストにストリーミングしています。ネットワークインターフェイス、ネットワーク、およびリモートサーバーが制限事項です。まず、DDのパフォーマンスを上げる必要があります。ディスクのバッファーメモリに合わせてbs =パラメーターを指定すると、ディスクのパフォーマンスが最大になります。たとえば、bs = 32Mと言います。これにより、gzipのバッファーがsataまたはsasのラインレートでドライブバッファーから満たされます。ディスクは、より良いスループットを提供するシーケンシャル転送に傾くでしょう。Gzipはストリーム内のデータを圧縮し、あなたの場所に送信します。NFSを使用している場合は、nfsの送信を最小限に抑えることができます。SSHを使用している場合、SSHカプセル化と暗号化のオーバーヘッドが発生します。netcatを使用している場合、暗号化はありません。


0

ここで、あなたが言及している「転送速度」はによって報告されていると仮定しますdd。実際にはdd1秒あたり10倍のデータ量を転送しているため、これは実際に意味があります。ただし、ddネットワーク経由での転送ではありませんgzip。そのジョブはプロセスによって処理されています。

コンテキスト:gzip内部バッファをクリアできる限り速く、入力パイプからデータを消費します。gzipのバッファが空になる速度は、いくつかの要因に依存します。

  • I / O書き込み帯域幅(ネットワークによってボトルネックになっており、一定のままです)
  • I / O読み取り帯域幅(最新のマシンのローカルディスクからの読み取り1MB / sよりもはるかに高くなるため、ボトルネックになる可能性は低い)
  • その圧縮率(10倍のスピードアップで約10%になると仮定します。これは、ログファイルやXMLなどの非常に繰り返しの多いテキストを圧縮していることを示しています)

そのため、この場合、ネットワークは100kB / sを処理できgzip、データを10:1前後で圧縮しています(CPUによってボトルネックになっていません)。これは、100kB / sを出力している間、1MB / sを消費gzipできることを意味し、消費率は見ることができるものです。dd

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.