Scp

為什麼 scp 這麼慢以及如何使它更快?

  • March 1, 2021

我正在嘗試複製一批文件,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 秒。

知道這個成本是從哪裡來的,有沒有辦法讓它更快?

@wurtel 的評論可能是正確的:建立每個連接都有很多成本。如果你能解決這個問題,你將獲得更快的傳輸(如果你不能,只需使用@roaima 的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
$ 

您可以使用rsync(over ssh),它使用單個連接來傳輸所有源文件。

rsync -avP cap_* user@host:dir

如果您沒有rsync(為什麼沒有!?),您可以使用tarwithssh像這樣,這樣可以避免創建臨時文件(這兩個替代方案是等效的):

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

在所有其他條件相同的情況下,這rsync是首選的,因為它可以在發生中斷時重新啟動。

引用自:https://unix.stackexchange.com/questions/238152