我手动将一个文件复制到一个服务器和同样的文件复制到一个SFTP服务器上。这个文件大小为140MB。
FTP:传输速率大约为11MB/s
SFTP:传输速率大约为4.5MB/s
我理解文件在发送之前必须进行加密。这是文件传输的唯一影响吗?(实际上这并不完全是传输时间,而是加密时间)。
我对这样的结果感到惊讶。
我手动将一个文件复制到一个服务器和同样的文件复制到一个SFTP服务器上。这个文件大小为140MB。
FTP:传输速率大约为11MB/s
SFTP:传输速率大约为4.5MB/s
我理解文件在发送之前必须进行加密。这是文件传输的唯一影响吗?(实际上这并不完全是传输时间,而是加密时间)。
我对这样的结果感到惊讶。
我是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电子邮件地址(谷歌搜索)随时给我发邮件。
因此,速度下降是由小数据包大小x每个数据包所需强制ACK响应引起的,这显然是不合理的。SFTP的本质及其对每个小数据块发送ACK的作用,使得初始天真的SFTP实现在通过高延迟网络发送数据时受到严重影响。如果您必须等待每个32KB数据的几百毫秒,那么永远不会有快速的SFTP传输。这种天真的实现是libssh2一直提供的,包括libssh2 1.2.7。
高性能SSH/SCP(HP-SSH)项目提供了一个OpenSSH补丁集,显然可以改进内部缓冲区并实现加密的并行化。但是请注意,即使是非并行版本的速度也超过了一些评论者所获得的40Mb/s未加密速度。修复涉及更改OpenSSH调用加密库的方式,而不是更改密码,AES128和AES256之间的速度没有任何差别。 加密需要一些时间,但它很小。 它可能在90年代很重要,但像Java与C的速度一样,现在已经不重要了。
多个因素影响SFTP传输速度:
push
命令,可以使用并行处理上传文件。push
机制时,吞吐量平均提高了2.5倍。这种方法适用于所有主要发行版上的标准OpenSSH服务器。它依赖于随机访问支持,因此在某些情况下可能无法正常工作,例如,当SFTP服务器具有指向基于云存储(如S3)的自定义文件系统时。你的结果很有道理。由于FTP在非加密通道上运行,因此比SFTP(它是基于SSH版本2协议的子系统)更快。还要记住,SFTP是基于数据包的协议,而FTP是基于命令的协议。
SFTP中的每个数据包在从客户端写入传出套接字之前都会被加密,然后在服务器接收时进行解密。这当然会导致传输速率变慢,但传输非常安全。使用诸如zlib之类的压缩算法可以改善SFTP的传输时间,但仍无法与明文FTP相比。也许更好的比较是将SFTP与FTPS进行比较,两者都使用加密?
SFTP的速度取决于用于加密/解密的密码,使用的压缩算法(例如zlib),用于套接字连接的数据包大小和缓冲区大小。
为了比较,我尝试从运行 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有许多工具可以实现这个功能。其中一个可能的方法是“流量塑形”。在办公环境中,通常会为业务关键活动保留带宽。同样,网站托管公司或您的ISP也可能出于类似的原因而进行操作。
你也可以在家里很简单地设置它。
例如,可以规定FTP保留最低带宽,而SFTP可能会受到“其他所有”规则的限制。或者可能会设定一个规则来限制SFTP的带宽,但与您同时使用SFTP的其他人也是如此。
所以:你从哪里传输文件,传到哪里呢?