为什么我通过SFTP传输文件时,比使用FTP传输时间更长?

68

我手动将一个文件复制到一个服务器和同样的文件复制到一个SFTP服务器上。这个文件大小为140MB。

FTP:传输速率大约为11MB/s

SFTP:传输速率大约为4.5MB/s

我理解文件在发送之前必须进行加密。这是文件传输的唯一影响吗?(实际上这并不完全是传输时间,而是加密时间)。

我对这样的结果感到惊讶。


p.s. 对于传输速度单位,您是指 Mb/s 吗? - Raptor
3
Mo是MB的法语缩写,“un octet”指的是一个字节。"Octo"在拉丁语中表示八。 - greut
1
SFTP的速度几乎总是比FTP或FTPS慢得多(通常相差数个数量级)。差异的原因在于SSH2协议中存在许多额外的数据包、加密和握手开销,而FTP则不必担心这些。FTP是一种非常简洁和相对简单的协议,几乎没有数据传输开销,并且该协议专门设计用于快速传输文件。加密会使FTP变慢,但远远达不到SFTP的水平。 - Alex
11个回答

190

我是HPN-SSH的作者,被这里的评论者要求发表意见。首先,需要注意的是SSHv2是一种多路复用协议,即在单个TCP连接上有多个通道。因此,SSH通道基本上不知道TCP使用的底层流量控制算法。这意味着SSHv2必须实现自己的流量控制算法。最常见的实现方式是重新实现滑动窗口,这意味着你需要在TCP滑动窗口上放置SSH滑动窗口。最终结果是接收缓冲区的有效大小是两个滑动窗口接收缓冲区的最小值。Stock OpenSSH具有最大接收缓冲区大小为2MB,但实际上更接近于约1.2MB。大多数现代操作系统都有一个缓冲区,可以通过自动调整接收缓冲区大小增长到4MB的有效大小。为什么这很重要?如果接收缓冲区大小小于带宽延迟乘积(BDP),则无论你的系统速度有多快,都永远无法完全填满管道。

这还受到SFTP在TCP和SSH流量控制之上添加另一层流量控制的事实的影响。SFTP使用未完成消息的概念。每个消息可以是命令、命令的结果或批量数据流。未完成的消息可能高达特定的数据报大小。因此,你最终将得到另一个接收缓冲区。该接收缓冲区的大小为数据报大小*最大未完成消息数(均可在命令行上设置)。默认值为32k * 64(2MB)。因此,在使用SFTP时,必须确保TCP接收缓冲区、SSH接收缓冲区和SFTP接收缓冲区大小足够(但不能过大,否则交互式会话中可能会出现过度缓冲问题)。

HPN-SSH通过最大缓冲区大小约为16MB来直接解决SSH缓冲问题。更重要的是,该缓冲区通过轮询TCP连接的缓冲区大小的proc条目动态增长到适当的大小(基本上在第3层和第4层之间打开一个洞)。这避免了几乎所有情况下的过度缓冲。在SFTP中,我们将最大未完成请求数提高到256。至少我们应该这样做——看起来这个更改没有按预期传播到6.3补丁集中(尽管它在6.2中)。我会很快修复这个问题。没有6.4版本,因为6.3可以很好地补丁到6.4(6.4只需要1行安全修复从6.3补丁)。

我知道这听起来很奇怪,但缓冲区的正确大小是性能方面单一最重要的变化。尽管许多人认为加密并不是大多数情况下性能不佳的真正原因。您可以通过将数据传输到越来越远的源端(就RTT而言)来证明这一点。你会注意到RTT越长,吞吐量就越低。这清楚地表明这是一个与RTT有关的性能问题。

总之,通过这个改变,我开始看到多达两个数量级的提高。如果您了解TCP,您就会理解为什么这样做有如此大的差异。这不是关于数据报的大小或数据包的数量或任何类似的东西。整个问题在于为了有效利用网络路径,您必须拥有一个接收缓冲区等于在两个主机之间可以传输的数据量。这也意味着,如果路径不足够快且足够长,则您可能根本看不到任何改进。如果BDP小于1.2MB,则HPN-SSH对您没有价值。

并行化的AES-CTR密码是在拥有多个核心的系统中进行完整加密的性能提升。通常情况下,我建议人们(或者控制服务器和客户端的人)使用NONE密码开关(加密身份验证,大量数据以明文传递),因为大多数数据并不是非常敏感。但是,这仅适用于像SCP这样的非交互式会话。在SFTP中无法工作。

还有其他一些性能改进,但没有什么比正确调整缓冲区和加密工作更重要的了。当我有空闲时间时,我可能会将HMAC过程流水线化(目前性能最慢的部分),并进行一些更小的优化工作。

那么,如果HPN-SSH如此出色,为什么OpenSSH没有采用它呢?这是一个漫长的故事,了解OpenBSD团队的人可能已经知道答案。我理解他们的许多原因 - 这是一个庞大的补丁,需要他们额外的工作(而他们是一个小团队),他们不像安全那样注重性能(尽管对于HPN-SSH没有安全影响),等等等。但是,即使OpenSSH没有使用HPN-SSH,Facebook也在使用它。 Google、Yahoo、Apple、大多数大型研究数据中心、NASA、NOAA、政府、军队和大多数金融机构也是如此。它在这一点上已经经过了很好的检验。

如果有任何问题,请随时提问,但我可能无法及时更新此论坛。您可以通过HPN-SSH电子邮件地址(谷歌搜索)随时给我发邮件。


9
SSH仍然非常慢,这个Bug严重影响了使用加密进行大量数据传输的效率。你最近联系过OpenSSH团队了吗?询问一下他们是否有兴趣解决这个问题。 - Indolering
有没有办法将此补丁应用于Win32-OpenSSH或cygwin? - rustyx
1
老实说,我不了解Win32-OpenSSH。但我知道,如果你已经运行了cygwin环境,你可以使用我的补丁集来修补基本的openssh代码。或者,如果你正在运行Windows 10,你可以使用bash shell(Bash on Ubuntu on Windows)并在那里使用HPN扩展来修补和编译OpenSSH。 - Chris Rapier
1
@ChrisRapier:如果您不介意的话,我有一个问题:)您能详细说明一下兼容性问题吗? HPN-SSH服务器是否能与SSH客户端正常工作?反之亦然?在每种情况下(原始或改进),性能如何? - user541686
2
在我测试过的所有场景中(非常之多),它与OpenSSH完全兼容。性能优势通常在HPN-SSH作为数据接收器时出现,因为更改的核心涉及接收器侧流量控制。请记住,只有当路径的BDP大于股票OpenSSH中的2MB限制时,才会出现此性能提升。 - Chris Rapier

18
更新: 正如评论者指出的那样,在此文章发布之前一段时间,我所描述的问题已经得到了解决。然而,我知道HP-SSH项目并请求作者发表意见。就像最受欢迎的答案中所解释的那样,加密不是问题的源头。感谢电子邮件和比我聪明的人!
哇,一个一年前的问题,只有错误的答案。然而,我必须承认,当我自己问同样的问题时,我假定减速是由于加密造成的。但是问问自己下一个逻辑问题:您的计算机加密和解密数据的速度有多快?如果您认为这个速度接近OP报告的4.5Mb /秒(约为0.5625MB / s,或大约是一个5.5英寸软盘的一半容量!),请用拳头打自己几次,喝些咖啡,再问一次相同的问题。 显然这与数据包大小选择上的疏忽有关,至少这是LIBSSH2作者所说的,

SFTP的本质及其对每个小数据块发送ACK的作用,使得初始天真的SFTP实现在通过高延迟网络发送数据时受到严重影响。如果您必须等待每个32KB数据的几百毫秒,那么永远不会有快速的SFTP传输。这种天真的实现是libssh2一直提供的,包括libssh2 1.2.7。

因此,速度下降是由小数据包大小x每个数据包所需强制ACK响应引起的,这显然是不合理的。

高性能SSH/SCP(HP-SSH)项目提供了一个OpenSSH补丁集,显然可以改进内部缓冲区并实现加密的并行化。但是请注意,即使是非并行版本的速度也超过了一些评论者所获得的40Mb/s未加密速度。修复涉及更改OpenSSH调用加密库的方式,而不是更改密码,AES128和AES256之间的速度没有任何差别。 加密需要一些时间,但它很小。 它可能在90年代很重要,但像Java与C的速度一样,现在已经不重要了。


6
抱歉,您的陈述只是不称职的。 加密确实有限制,会影响快速系统上的数据传输。 您引用的内容早在约2007年就已被知晓并被所有库(包括OpenSSH)实现。 HP-SSH则是另一个故事。 现在,如果您将FTP和SFTP在同一台计算机和网络上进行比较,并使用最佳代码(不会由于糟糕的设计或实现错误而导致缓慢),SFTP始终比FTP慢。 - Eugene Mayevski 'Callback
哦,好吧,文件上的日期相当旧了!HP-SSH基准测试似乎与其他人报告的数字相符(尽管OP在mb/MB符号方面有些粗心)。如果这些是已解决的问题,那么为什么HP-SSH仍然存在呢?你能否建议一下修改? - Indolering
此外,那篇关于LIBSSH的文章是2010年的,所以......顺便说一句,我已经给HP-SSH的人发了电子邮件,请他们发表意见。 - Indolering
HP-SSH的作用是通过并行加密来加快加密速度。这是一个棘手的问题,确实可以显著提高速度。 - Eugene Mayevski 'Callback
HP-SSH在调整网络连接的同时,还可以并行化加密。如果您查看他们的并行化基准测试,可以看到他们使用2008年的8核CPU时,达到了400(AES 256)到500 mb/s(AES 128)的速度。即使我们纠正了OP的mb/MB错误,这个速度也比他应该得到的原始输出慢一个数量级。不过,如果他连接到一个共享主机的话... - Indolering

11

多个因素影响SFTP传输速度:

  1. 加密。虽然对称加密速度很快,但在快速网络(100mbit或更高)上比较速度时,加密会成为您进程的瓶颈。
  2. 哈希计算和检查。
  3. 缓冲区复制。在SSH上运行的SFTP比普通FTP多至少6次数据块复制(每边3次),而普通FTP中,数据在最佳情况下可以直接传递到网络接口而无需复制。并且块复制也需要一些时间。

3
对于那些仍在寻找答案并且不想使用OpenSSH补丁的人来说,我是一个名为Push SFTP的开源GPL项目的作者,该项目可以在GitHub上找到。它是一个命令行客户端,类似于标准的SFTP命令,它添加了一个push命令,可以使用并行处理上传文件。
它不需要经过补丁的OpenSSH版本,并且测试表明,在使用push机制时,吞吐量平均提高了2.5倍。这种方法适用于所有主要发行版上的标准OpenSSH服务器。它依赖于随机访问支持,因此在某些情况下可能无法正常工作,例如,当SFTP服务器具有指向基于云存储(如S3)的自定义文件系统时。
此外,作为支持该客户端的开源Java SSH库Maverick Synergy的开发者,我们已经在API中构建了支持,供其他开发者在其项目中使用。

2
SFTP几乎总是比FTP或FTPS慢得多(通常相差数个数量级)。差异的原因在于SSH2协议中存在许多附加数据包、加密和握手开销,而FTP则不必担心这些问题。FTP是一种非常简洁且相对简单的协议,几乎没有数据传输开销,并且该协议专门设计用于快速传输文件。加密会使FTP变慢,但远远不到SFTP的水平。
SFTP运行在SSH2上,更容易受到网络延迟和客户端、服务器机器资源限制的影响。增加的敏感性是由于每个客户端和服务器之间发送的数据包都涉及额外的数据握手,并且解码SSH2数据包的复杂性也更高。SSH2被设计为Telnet和其他不安全的远程shell的替代品,而不是用于非常高速的通信。SSH2提供的灵活性可以安全地打包和传输几乎任何类型的数据,这也为协议带来了大量的附加复杂性和开销。
但是,如果具备正确的网络条件,则仍然有可能在客户端和服务器之间使用SFTP获得几MB/s的数据传输速率。尝试最大化SFTP传输速度时,请检查以下项目:
你的网络中是否存在检查或限制SSH2流量的防火墙或网络设备?这可能会减慢传输速度。请检查防火墙设置。我们曾经有用户报告通过修改防火墙规则解决极慢的SFTP文件传输问题。 你使用的SFTP客户端可能会产生很大的影响。尝试使用几个不同的SFTP客户端,看看是否会得到不同的结果。 网络延迟会严重影响SFTP。如果你所在的链接具有高延迟程度,那么快速传输将是一个问题。 服务器机器的性能如何?SFTP加密非常耗费资源。确保你有足够强大的机器,在SFTP文件传输期间不会被过度利用(高CPU利用率)。
更多信息请参见:https://support.cerberusftp.com/hc/en-us/articles/203333215-Why-is-SSH2-SFTP-so-much-slower-than-FTP-and-FTPS-

2
加密不仅会增加CPU负担,还会增加一些网络开销。

@ShivanRaptor,它通常是默认启用的吗?SFTP和SCP有很大的区别吗? - Michael Krelin - hacker
压缩并不总是更快的。如果您拥有高速网络(例如:局域网),CPU开销实际上会使传输变慢(甚至相当慢)。 - WhyNotHugo
1
@Hugo,如果你有一些低端的NAS在压缩端,尤其是。;-) - Michael Krelin - hacker
1
@MichaelKrelin-hacker 虽然这是相当正确的(并且绝对是我的情况),但通常在千兆网络上,压缩不会带来任何收益,甚至可能会降低吞吐量(正如我用两台支持AESNI的笔记本电脑测试过的那样)。 - WhyNotHugo
@Hugo,我不否认这一点。大多数情况下肯定是这样,但可能取决于数据的可压缩性和存储速度。 - Michael Krelin - hacker
显示剩余4条评论

1

你的结果很有道理。由于FTP在非加密通道上运行,因此比SFTP(它是基于SSH版本2协议的子系统)更快。还要记住,SFTP是基于数据包的协议,而FTP是基于命令的协议。

SFTP中的每个数据包在从客户端写入传出套接字之前都会被加密,然后在服务器接收时进行解密。这当然会导致传输速率变慢,但传输非常安全。使用诸如zlib之类的压缩算法可以改善SFTP的传输时间,但仍无法与明文FTP相比。也许更好的比较是将SFTP与FTPS进行比较,两者都使用加密?

SFTP的速度取决于用于加密/解密的密码,使用的压缩算法(例如zlib),用于套接字连接的数据包大小和缓冲区大小。


为什么这个被踩了?其中一部分是准确、正确的,比其他得分非负的答案更相关。 - MattBianco

1

SFTP不是SSH上的FTP,它是一种不同的协议,类似于SCP,提供更多功能


0

为了比较,我尝试从运行 Raring Ringtail Ubuntu alpha 2 live cd 的 i5 笔记本电脑向运行 Ubuntu 12.04.1 的 i7 台式机传输一个299GB的ntfs磁盘映像。报告的速度如下:

通过wifi + powerline: scp:5MB/秒(40 Mbit/秒)

通过千兆以太网 + Netgear G5608 v3:

scp:44MB/秒

sftp:47MB/秒

sftp -C:13MB/秒

因此,在良好的千兆链接下,sftp 略快于 scp,2010年代的快速 CPU 足够快以进行加密,但并不是所有情况下压缩都是优势。

在一个糟糕的千兆以太网连接下,我发现 sftp 比 scp 的表现好得多。scp 太啰嗦了,可以看看 2008 年 comp.security.ssh 上的“scp UNBELIEVABLY slow”: https://groups.google.com/forum/?fromgroups=#!topic/comp.security.ssh/ldPV3msFFQw http://fixunix.com/ssh/368694-scp-unbelievably-slow.html

0

有许多工具可以实现这个功能。其中一个可能的方法是“流量塑形”。在办公环境中,通常会为业务关键活动保留带宽。同样,网站托管公司或您的ISP也可能出于类似的原因而进行操作。

你也可以在家里很简单地设置它。

例如,可以规定FTP保留最低带宽,而SFTP可能会受到“其他所有”规则的限制。或者可能会设定一个规则来限制SFTP的带宽,但与您同时使用SFTP的其他人也是如此。

所以:你从哪里传输文件,传到哪里呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接