Ruby 和 Net::SCP 传输(套接字)的性能问题

Posted

技术标签:

【中文标题】Ruby 和 Net::SCP 传输(套接字)的性能问题【英文标题】:Performance issues with Ruby and Net::SCP transfers (sockets) 【发布时间】:2011-05-11 15:38:03 【问题描述】:

从命令行 scp 实用程序的能力来看,库中的 SCP 上传速度似乎受到很大限制。我知道这是 Ruby (1.9.2-p0),但 Net::SCP 比 Linux 实用程序慢大约 8 倍(使用大文件...见下文)。我很好奇知道(我快速查看了代码)这是 Ruby 中的套接字,还是可以更好地多路复用 Net::SCP 套接字?

我注意到,无论我尝试何种上传方式(串行上传、异步操作的通道、使用 scp 对象的多个实例),我都无法在 SCP 上传上获得超过 9 兆字节/秒的传输速度。现在...让我解释一下我的调查细节:

1) 尝试了不同的加密算法

我使用了不同类型的加密,速度没有太大变化 示例:我可以使用命令行 scp(加密算法 = arcfour128)提交我的 1GB 测试文件,并在我的内部千兆位连接上获得 73.3 兆字节/秒的传输速率。我使用 Net::SCP.upload 库的内部千兆位连接速度从未超过 9 兆字节/秒。

2) 尝试了不同的主机/操作系统

我发现 Linux -> Linux 上传速度最快。 SUA 的 ssh 服务器 (Windows) 只能为我提供最高 13.5 兆字节/秒的上传速度(Linux -> Windows,使用带有 scp 命令行的 arcfour 算法),而 Linux -> Linux(使用 arcfour,带有 scp 命令行) ) 是惊人的 73.3 兆字节/秒。我应该提一下,这些 Windows 和 Linux 机器是完全相同的型号、硬件等。

3) 尝试了不同的 SCP 上传方法

-> 用了2个同步上传!电话,一个接一个打完。 -> 使用了 2 个异步上传调用,一个接一个地开始了 -> 使用了 2 个 Net::SCP 对象并将文件提交到上传的非阻塞/异步版本(因此它们并行运行) 这些不同的方法都不是提供任何显着的性能提升,这有点令人沮丧。

以下是测试结果(文本增强了可读性,但类似于所提供代码的输出):


Net::SCP
Done creating channels
Starting transfer of /home/seth/afpcases/systeme.afp # two upload! calls, one after another
Finished transfer of /home/seth/afpcases/systeme.afp
--> Duration: 126.07707 seconds (8.7168903909331 megabytes/s) should show transfer speed of serial uploads

Starting transfer of /home/seth/afpcases/systeme.afp # two upload calls, one after another, with a wait on both channels after both have started
Finished transfer of /home/seth/afpcases/systeme.afp
--> Duration: 122.588784 seconds (8.964931082112699 megabytes/s) should show transfer speed of simultaneous async channels.

Starting transfer of /home/seth/afpcases/systeme.afp # two upload calls on two separate Net::SCP objects, one after another, with a wait on both channels after both have started
Finished transfer of /home/seth/afpcases/systeme.afp
--> Duration: 122.822663 seconds (8.947860054133495 megabytes/s) should show transfer speed of simultaneous SCP instances

Finished in 371.761262 seconds

如果您有一个大文件(我使用了大约 1GB 的文件),您可以使用这些 rspec 测试(在 scp_spec.rb 中)或将它们更改为您熟悉的任何测试工具来查看这种性能下降。

如果您不知道如何在库中提高这种性能,除了通过子 shell 调用 scp 实用程序之外,您对如何打开一些额外的 SCP 传输并行速度还有什么想法吗?

Rspec 测试在这里:https://gist.github.com/703966

【问题讨论】:

【参考方案1】:

可能是时代变了,但是在我当前的安装(Ruby 2.7,net-scp 3.0.0)中,使用 rspec 文件使用 Ruby 的 Net::SCP 的速度以及我从命令行工具获得的结果大致相同(并行作业比单个命令行调用稍快,但这是意料之中的)。

我发现唯一奇怪的是,您的 rspec 为每个测试上传了两次文件,然后使用总时间和文件大小计算性能 - 这将给出的结果似乎是性能的一半实际上是这样 - 例如:如果测试 10GB 文件需要 10 秒,那么性能将报告为 1 Gbps,而实际上是 2 Gbps,因为在 10 秒内传输了 20 GB。

【讨论】:

【参考方案2】:

您可以改用Net-sftp。 Sftp 是一种较新的协议,如果 sftp 协议可用,linux scp 实用程序实际上会使用它。我不知道 net-scp 是否真的使用 sftp 协议,但如果没有,我不会感到惊讶。

您也可以尝试rsync,但这也需要在远程主机上安装 rsync。到目前为止,rsync 是远程文件传输速度之王,尽管我不能保证 6 个 rsync gem。

【讨论】:

以上是关于Ruby 和 Net::SCP 传输(套接字)的性能问题的主要内容,如果未能解决你的问题,请参考以下文章

ruby 在Ruby中尝试使用分叉和unix套接字

通过 SO_RCVTIMEO 套接字选项在 Ruby 中设置套接字超时

在 Ruby 中将 UDP 套接字绑定到通配符主机

使用perl实现scp批量分发

如何与 Ruby 中的线程通信?

Ruby在recv时检测套接字关闭