Ruby

Net::SFTPのdownloadメソッドは異常に遅い

More than 1 year has passed since last update.


Net::SFTPとは

Rubyでリモートホストにファイルをコピーする一つの手段として、Net::SFTP というgemがある。

最小限の使い方は以下の通り。gem install net-sftpしてから

require 'net/sftp'

Net::SFTP.start('host', 'username', :password => 'password') do |sftp|
# upload a file or directory to the remote host
sftp.upload!("/path/to/local", "/path/to/remote")

# download a file or directory from the remote host
sftp.download!("/path/to/remote", "/path/to/local")
end

また、Net::SSHと一緒に使う場合は以下のようにもかける。

require 'net/ssh'

require 'net/sftp'

Net::SSH.start('remote_host') do |ssh|
ssh.sftp.download!("/path/to/remote", "/path/to/local")
end

pure ruby実装なので、速度が気になる。ファイル転送速度をrsyncやscpと比較してみた。


速度比較

対象とするファイルは2つ。136MBのテキストファイルと、約1GBのbzip2圧縮されたバイナリファイル。

2つのマシンでの転送速度を比較した。


使ったrubyコード

require 'net/ssh'

require 'net/sftp'

Net::SSH.start('remote_host') do |ssh|
ssh.sftp.download!(ARGV[0], ARGV[1])
# ssh.sftp.upload!(ARGV[0], ARGV[1])
end


使用したrubyおよびrsync


  • ruby 2.5.0


    • net-ssh 4.2.0

    • net-sftp 2.1.2



  • rsync 2.6.9


結果

結果は以下の通り。それぞれ転送にかかった時間を表している。

rsyncは圧縮あり(-z)の場合となしの場合も比較した。

uploadの場合

136MB text file
1GB binary file

rsync -az
6.7
12.9

rsync -a
3.4
16.9

scp
3.3
14.3

Net::SFTP
5.4
21.3

downloadの場合

136MB text file
1GB binary file

rsync -az
6.9
13.9

rsync -a
4.9
16.7

scp
3.4
9.7

Net::SFTP
61.6
> 300

当然ながらrsyncの方がNet::SFTPより速いのだが、uploadの場合はSFTPがrsyncより極端に遅いというわけではない。

しかし、downloadの場合はSFTPが極端に遅い。

実装がどうなっているのかは確認していないが、Net::SFTPのdownloadを使う場合は気をつける必要がありそうだ。