我需要将一个 20 GB KVM vdisk 文件(存储 CentOS 6.5 VM 的根文件系统)从一台实验室服务器传输到另一台。大文件大小以及我曾经将这样的 vdisk 文件压缩到几百兆字节的事实使我本能地启用了压缩,scp
但我惊讶地发现传输速度相当低。然后我尝试与andbzip2
结合并被吓了一跳。这是方法和平均吞吐量的摘要。ssh
cat
scp -C vm1-root.img [email protected]:/mnt/vdisks/
, 11 MB/秒。bzip2 -c vm1-root.img | ssh -l root 192.168.161.62 "bzip2 -d -c > /mnt/vdisks/vm1-root.img"
, 5 MB/秒。这个更低的结果促使人们在网上搜索。scp -c arcfour -C vm1-root.img [email protected]:/mnt/vdisks/
, 13 MB/秒。在关于 serverfault的一个答案-c arcfour
中建议使用as。它几乎没有帮助。最后,我禁用了压缩。scp vm1-root.img [email protected]:/mnt/vdisks/
, 23 MB/秒。
压缩不应该更快吗?
在收到ssh(1)
来自@sven 的手册页提示后,我尝试了几种不涉及压缩的文件传输替代方法,两者都取得了更好的结果。
cat vm1-root.img | ssh -l root 192.168.161.62 "cat > /mnt/vdisks/vm1-root.img"
, 26 MB/秒。nc -l 5678 > /mnt/vdisks/vm1-root.img
在接收器和nc 192.168.161.62 5678 < vm1-root.img
发射器上,40 MB/s。该端口5678
是可用的任意端口。
使用nc
原来是最快的复制方法!
过去,scp -C
每当我认为它会时,它都工作得很好。例如,传输/var/log/messages*
几 GB 大小的 syslog ( ) 时。几百 KB/s 的未压缩传输速率将增加到 1-2 MB/s。如手册页中所指出的,此示例确实适用于连接缓慢的情况。
我有一个案例,为 20 GB 分区新创建的虚拟磁盘映像的压缩大小仅为 200 MB。以大约 25 MB/s 的传输速率,我们可以在 8 秒内完成复制,而不是超过 13 分钟!显然,scp
在这种情况下,没有压缩是低效的,scp -C
甚至更糟。
我想,这里学到的主要教训是,scp -C
应该被认为只是一种方便。如果一个文件可以显着压缩,那么最好先在源上压缩它,然后传输压缩形式,最后在目标上解压。快速进行压缩和解压缩的工具(例如pbzip2)将有更大的帮助。
引用
man ssh
(这是 所使用的基础scp
):问题是压缩数据比通过网络发送数据需要更多时间。
此外,除了压缩之外,nc 获得最佳速率,因为它也不加密。无损压缩依赖于查找数据的冗余部分,当在网络级别完成时,您最多可以查看 [buffer-size] 字节,而当首先处理整个文件时,它是 [file-size] 字节在其中寻找和处理重复的字节句子。
此外,对于移动磁盘映像,您应该使用文件系统感知工具,例如 ntfsclone/partclone,因为即使是压缩也无法简单地跳过未分配的块 - 如果您不必传输任何数据,您的传输速率是无限的。也不要忘记销毁 Windows 分区上的交换和休眠文件,否则你正在复制垃圾,它只会扔掉并重新创建。