为什么 scp 这么慢以及如何让它更快?

为什么 scp 这么慢以及如何让它更快?

我正在尝试复制一批文件,scp但速度非常慢。这是一个包含 10 个文件的示例:

$ time scp cap_* user@host:~/dir
cap_20151023T113018_704979707.png    100%  413KB 413.2KB/s   00:00    
cap_20151023T113019_999990226.png    100%  413KB 412.6KB/s   00:00    
cap_20151023T113020_649251955.png    100%  417KB 416.8KB/s   00:00    
cap_20151023T113021_284028464.png    100%  417KB 416.8KB/s   00:00    
cap_20151023T113021_927950468.png    100%  413KB 413.0KB/s   00:00    
cap_20151023T113022_567641507.png    100%  413KB 413.1KB/s   00:00    
cap_20151023T113023_203534753.png    100%  414KB 413.5KB/s   00:00    
cap_20151023T113023_855350640.png    100%  412KB 411.7KB/s   00:00    
cap_20151023T113024_496387641.png    100%  412KB 412.3KB/s   00:00    
cap_20151023T113025_138012848.png    100%  414KB 413.8KB/s   00:00    
cap_20151023T113025_778042791.png    100%  413KB 413.4KB/s   00:00    

real    0m43.932s
user    0m0.074s
sys 0m0.030s

奇怪的是,传输速率约为 413KB/s,文件大小约为 413KB,因此实际上应该每秒传输一个文件,但每个文件大约需要 4.3 秒。

知道这个开销从何而来,有什么方法可以让它更快吗?

答案1

您可以使用rsync(over ssh),它使用单个连接来传输所有源文件。

rsync -avP cap_* user@host:dir

如果您没有rsync(为什么不!?),您可以像这样使用tarwith ssh,这可以避免创建临时文件(这两种选择是等效的):

tar czf - cap_* | ssh user@host tar xvzfC - dir
tar cf - cap_* | gzip | ssh user@host 'cd dir && gzip -d | tar xvf -'

rsync在其他条件相同的情况下,这是首选,因为它可以在发生中断时重新启动。

答案2

@wurtel 的评论可能是正确的:建立每个连接都有很多开销。如果你能解决这个问题您将获得更快的传输速度(如果不能,只需使用@罗艾玛的rsync解决方法)。我做了一项实验,将类似大小的文件(head -c 417K /dev/urandom > foo.1并制作了该文件的一些副本)传输到需要一段时间才能连接的主机(HOST4)和响应速度非常快的主机(HOST1):

$ time ssh $HOST1 echo


real    0m0.146s
user    0m0.016s
sys     0m0.008s
$ time scp * $HOST1:
foo.1                                         100%  417KB 417.0KB/s   00:00    
foo.2                                         100%  417KB 417.0KB/s   00:00    
foo.3                                         100%  417KB 417.0KB/s   00:00    
foo.4                                         100%  417KB 417.0KB/s   00:00    
foo.5                                         100%  417KB 417.0KB/s   00:00    

real    0m0.337s
user    0m0.032s
sys     0m0.016s
$ time ssh $HOST4 echo


real    0m1.369s
user    0m0.020s
sys     0m0.016s
$ time scp * $HOST4:
foo.1                                         100%  417KB 417.0KB/s   00:00    
foo.2                                         100%  417KB 417.0KB/s   00:00    
foo.3                                         100%  417KB 417.0KB/s   00:00    
foo.4                                         100%  417KB 417.0KB/s   00:00    
foo.5                                         100%  417KB 417.0KB/s   00:00    

real    0m6.489s
user    0m0.052s
sys     0m0.020s
$ 

答案3

转会谈判需要时间。一般来说,操作n文件的每个字节比单个文件上的单个操作花费的时间要长得多n*字节。例如对于磁盘 I/O 也是如此。

如果你仔细观察,你会发现这种情况下的传输速率是文件大小/秒。

要更有效地传输文件,请将它们与 捆绑在一起tar,然后传输 tarball:

tar cvf myarchive.tar cap_20151023T*.png

或者,如果您还想压缩存档,

tar cvzf myarchive.tar.gz myfile*

是否压缩取决于文件内容,例如。如果它们是 JPEG 或 PNG,压缩不会产生任何效果。

答案4

scp 比应有的速度慢的另一个原因(尤其是在高带宽网络上)是它具有静态定义的内部流量控制缓冲区,这些缓冲区最终会成为网络性能瓶颈。

HPN-SSH是 OpenSSH 的修补版本,它增加了这些缓冲区的大小。它使一个大量的与 scp 传输速度的差异(请参阅网站上的图表,但我也是从个人经验出发)。当然,要获得这些好处,您需要在所有主机上安装 HPN-SSH,但如果您经常需要传输大文件,那么这是非常值得的。

相关内容