scp 传输单个文件的速度相当慢。最快的方法是什么?
我需要速度的原因不是因为我有大量文件需要传输。我只是希望单个文件传输(从开始到结束)能够快速完成(因此 rsync 和 tar 以及 transfer 不够快)。
答案1
传输大量小文件有很多限制。一些已经提到过:网络延迟、磁盘写入速度等。但是,大多数限制可以通过使用“rsync”进行优化。如果目标上不存在文件,并且您非常确定该过程不会被中断,则使用 tar 管道传输到 tar 将非常高效:
cd /SOURCE/DIR && tar cf - . | ssh DESTINATIONHOST "cd /DESTINATION/DIR && tar xpvf -"
从根本上来说您需要将所有文件批量处理,以便 SCP 的启动/关闭开销仅发生一次。如果您对每个文件都执行启动/关闭,那么效率将非常低。上面的“tar”管道将执行此操作。事实上,90% 的用例都这样就足够了。
这种“tar 管道”具有并行处理的优点(在一个进程中读取,而在另一个进程中写入)。但是,它受到以下几点限制:
- TCP/IP 永远不会 100% 利用其现有的管道。
- 每个进程都受到磁盘的限制,每次只能执行一次写入或一次读取。如果您使用旋转磁盘,那就没问题。如果您使用 SSD 或 RAID(允许多次并行读取的 RAID 类型),则此技术的性能会不佳。
您可以通过各种方法解决 #2,例如运行两个或多个进程,每个进程处理文件的一个子集。但是这些方法并不完善,而且有点马虎。
TCP/IP 更难解决,并且将继续成为您的限制。事实上,如果您调整系统以使一切都达到最佳状态,TCP/IP 将不会使用整个管道。每次 TCP/IP 认为它已经找到了最佳发送速率时,它都会尝试多发送一点以测试是否有“更多空间”可用。这会失败,TCP/IP 会稍微后退一点。这种不断增加/失败/后退的循环意味着 TCP/IP 流将在 100% 利用率和 50% 利用率之间交替……结果是管道的平均利用率为 75-80%。(注意:这些是估计值……进行一些谷歌搜索以找到确切的数字。关键是它将是 100% 和非 100% 的平均值,因此它永远不会是 100%)。
如果您运行多个 TCP/IP 流,它们将不断循环通过此增加/失败/后退循环。如果您运气不好,它们将同时发生碰撞,并且全部后退很远,导致管道利用率不足。如果您运气好,它们碰撞的次数会减少,您将得到一个看起来像许多弹跳球的图表……总体而言,管道利用率仍然不足。
哦,如果您有一台机器的 TCP/IP 实现没有最新的优化,或者没有完美调整,它会导致整个系统失控。
那么,如果 TCP/IP 如此糟糕,我们为什么还要继续使用它呢?在许多不同类型的流量共享管道的典型情况下,它并没有那么糟糕。这里的问题是,您有一个非常具体的应用程序,具有非常具体的要求。因此,您需要一个非常具体的解决方案。幸运的是,很多人也处于您的位置,因此这些解决方案变得越来越容易找到。
类似的系统http://asperasoft.com/使用 UDP/IP 上的自定义协议,以便控制退避/重试算法。他们使用前向纠错(FEC)这样小错误就不需要重新传输(对于 TCP/IP,小错误就是退避信号)、自定义压缩方案、增量复制以及他们自己的退避算法和速率限制系统,以实现管道的完全(或接近完全)利用。这些都是专有的,因此不清楚 Aspera 及其竞争对手究竟使用了哪些技术,也不清楚它们究竟如何工作。
许多公司都发明了这样的系统,并将其作为自己产品的一部分,或将其作为商业产品出售。
我目前不知道任何开源实现。(我希望得到纠正!)
如果这是一个非常紧迫的问题,值得花钱解决,请尝试使用商业产品之一。或者,如果您无法更改软件,则需要购买更大的管道。幸运的是,10G 和 40G 网络接口的价格正在下降。
答案2
William Glick 开发了一个优雅的解决方案:并行化 rsync。
/bin/bash
# SETUP OPTIONS
export SRCDIR="/folder/path"
export DESTDIR="/folder2/path"
export THREADS="8"
# RSYNC TOP LEVEL FILES AND DIRECTORY STRUCTURE
rsync -lptgoDvzd $SRCDIR/ /$DESTDIR/
# FIND ALL FILES AND PASS THEM TO MULTIPLE RSYNC PROCESSES
cd $SRCDIR; find . -type f | xargs -n1 -P$THREADS -I% rsync -az % /$DESTDIR/%
# IF YOU WANT TO LIMIT THE IO PRIORITY,
# PREPEND THE FOLLOWING TO THE rsync & cd/find COMMANDS ABOVE:
# ionice -c2
神奇的是,xargs -P
它会自动将输入分割成$THREADS
块。快速、高效、简单。
看威廉的原始出版物了解详情。