我想通过 100 Mbit/s 线路将我网络中的一台计算机的路径备份到同一网络中的另一台计算机。为此,我做了
dd if=/local/path of=/remote/path/in/local/network/backup.img
这让我的网络传输速度非常低,大约 50 到 100 kB/s,这需要很长时间。所以我停止了它,并决定尝试即时压缩它以使其更小,以便传输量更少。所以我这样做了
dd if=/local/path | gzip > /remote/path/in/local/network/backup.img.gz
但现在我的网络传输速度大约为 1 MB/s,快了 10 到 20 倍。注意到这一点后,我在多个路径和文件上进行了测试,结果始终如一。
为什么管道传输dd
还会gzip
大幅提高传输速率,而不是仅大幅减少流的字节长度?我原本以为传输速率会略有下降,因为压缩时 CPU 消耗更高,但现在我得到了双倍的提升。并不是说我不高兴,只是好奇而已。;)
答案1
dd
默认情况下使用非常小的块大小——512 字节(!!)。也就是说,有很多小的读取和写入。似乎dd
在您的第一个示例中天真地使用了,生成了大量具有非常小的有效负载的网络数据包,从而降低了吞吐量。
另一方面,gzip
它足够智能,可以使用更大的缓冲区进行 I/O。也就是说,通过网络进行的大量写入次数较少。
您能否dd
使用更大的bs=
参数再试一次,看看这次是否效果更好?
答案2
有点晚了,但我可以补充一下......
在一次采访中我被问到克隆逐位数据最快的方法是什么并粗略地回应使用dd
或dc3dd
(国防部资助)。面试官确认管道传输dd
到dd
更有效,因为这样可以简单地允许同时读/写或者用程序员的术语来说stdin/stdout
,从而最终使写入速度加倍,传输时间减半。
dc3dd verb=on if=/media/backup.img | dc3dd of=/dev/sdb
答案3
Cong 是正确的。您正在将块从磁盘以未压缩的形式传输到远程主机。您的网络接口、网络和远程服务器是限制因素。首先,您需要提高 DD 的性能。指定与磁盘缓冲内存一致的 bs= 参数将从磁盘获得最佳性能。例如,假设 bs=32M。然后,这将以 sata 或 sas 线速从驱动器缓冲区直接填充 gzip 的缓冲区。磁盘将更倾向于顺序传输,从而提供更好的吞吐量。Gzip 将压缩流中的数据并将其发送到您的位置。如果您使用的是 NFS,这将使 nfs 传输最小化。如果您使用的是 SSH,那么您将产生 SSH 封装和加密开销。如果您使用 netcat,那么您就没有加密开销。
答案4
我假设你提到的“传输速度”是由 报告的dd
。这确实有道理,因为dd
实际上每秒传输的数据量是原来的 10 倍!但是,dd
并未通过网络传输 — — 该作业正在由该gzip
进程处理。
一些背景信息:gzip
将以清除内部缓冲区的速度从输入管道消耗数据。gzip
缓冲区清空的速度取决于以下几个因素:
- I/O 写入带宽(受网络限制,且一直保持不变)
- I/O 读取带宽(这将远高于现代机器上从本地磁盘读取的 1MB/s,因此不太可能成为瓶颈)
- 它的压缩率(我假设你的 10 倍加速大约为 10%,这表明你正在压缩某种高度重复的文本,如日志文件或某些 XML)
因此,在这种情况下,网络可以处理 100kB/s,并将gzip
数据压缩到 10:1 左右(并且不会受到 CPU 的瓶颈影响)。这意味着,虽然它输出 100kB/s,但gzip
可以消耗1MB/s,消耗的速度是dd
看得见的。