反向多路复用可加快文件传输速度


19

我已经从一台机器向另一台机器发送了大量数据。如果我使用rsync(或任何其他方法)发送,它将以稳定的320kb / sec速度运行。如果我一次启动两次或三次传输,每次将进行320次,如果一次执行四次,则它们将使链接最大化。

我需要能够尽快发送数据,因此我需要一个可以对文件传输进行反向多路复用的工具。我需要一个通用的解决方案,因此在源计算机上运行split并在另一端将它们组合在一起是不切实际的。我需要它以自动化的方式工作。

是否有执行此操作的工具,或者我需要自己制作?发送者是CentOS,接收者是FreeBSD。

Answers:


29

证明全部加起来-我介绍了远程镜像命令的“圣杯”。感谢davr的lftp建议。

lftp -c "mirror --use-pget-n=10 --verbose sftp://username:password@server.com/directory" 

上面的内容将递归地镜像一个远程目录,将每个文件在传输时分成10个线程!


lftp很棒,但是在上载时我无法让它做多部分。我正在使用mirror --use-pget-n=20 -R-但似乎--use-pget-n仅在下载时有效。
2013年

PS,-P20可以上传多个文件,但是我不能对每个文件进行分段。
2013年

1
lftp不支持分段/分段上传。您需要从目标端启动传输才能使用pget -n
apraetor

记住,mirror是双向的;该pget参数仅适用于正在下载的文件。
apraetor

10

有一些可能有效的工具。

  • LFTP-支持FTP,HTTP和SFTP。支持使用多个连接下载单个文件。假设要将文件从remoteServer传输到localServer,在localServer上安装LFTP,然后运行:

    lftp -e 'pget -n 4 sftp://userName@remoteServer.com/some/dir/file.ext'

    “ -n 4”是要并行使用的连接数。

  • 然后有许多“下载加速器”工具,但它们通常仅支持HTTP或FTP,您可能不想在远程服务器上进行设置。一些示例是Axelaria2ProZilla


8

如果您使用的文件很少且很大lftp -e 'mirror --parallel=2 --use-pget-n=10 <remote_dir> <local_dir>' <ftp_server>:您将下载2个文件,每个文件分为10个片段,共有20个ftp连接<ftp_server>;

如果您有大量的小文件,请使用lftp -e 'mirror --parallel=100 <remote_dir> <local_dir>' <ftp_server>:然后,您将并行下载100个文件,而不会进行分段。总共将打开100个连接。这可能会耗尽服务器上的可用客户端,或者使您无法使用某些服务器。

您可以使用--continue恢复作业:)和-R上载而不是下载的选项(然后将参数顺序切换为<local_dir> <remote_dir>)。


1
参数中的错字:--use-pget-n而不是--use-pget-m。试图编辑,但我的编辑很短。
托尼

2

您可能可以调整TCP设置以避免此问题,具体取决于导致每个连接限制320KB / s的原因。我的猜测是,这不是 ISP对每个连接速率的明确限制。节流的原因可能有两个:

  1. 两台计算机之间的某些链接已饱和,并且丢包。
  2. 由于带宽延迟乘积太大,TCP窗口已饱和。

在第一种情况下,每个TCP连接将在标准TCP拥塞控制中有效竞争。您还可以通过更改拥塞控制算法或减少退避量来改善这一点。

在第二种情况下,您不受丢包的限制。添加额外的连接是扩大总窗口大小的粗略方法。如果您可以手动增加窗口大小,该问题将消失。(如果连接等待时间足够长,则可能需要TCP窗口缩放。)

您可以通过将往返“ ping”时间乘以连接的总速度来判断大约需要多大的窗口。1280KB / s的往返行程每毫秒需要1280(1024 = 1K的1311)个字节。一个64K缓冲区将以大约50毫秒的延迟达到最大,这是非常典型的。然后,一个16K的缓冲区将饱和在320KB / s左右。


1

您的数据如何组织?一些大文件?一些大目录?您可以在目录树的特定分支上生成rsync的多个实例。

这完全取决于您的源数据的结构。有大量的unix工具可以切片,切块和重新组装文件。


任意数据。有时它是一个大目录,有时是一个文件。
ZimmyDubZongyZongDubby

1

如果可以设置无密码的ssh登录,则将打开4个并发的scp连接(-n),每个连接处理4个文件(-L):

找 。型f | xargs -L 4 -n 4 /tmp/scp.sh user @ host:path

文件/tmp/scp.sh:

#!/bin/bash

#Display the help page
function showHelp()
{
    echo "Usage: $0 <destination> <file1 [file2 ... ]>"
}

#No arguments?
if [ -z "$1" ] || [ -z "$2" ]; then
    showHelp
    exit 1
fi

#Display help?
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
    showHelp
    exit 0
fi

#Programs and options
SCP='scp'
SCP_OPTS='-B'
DESTINATION="$1";shift;

#Check other parameters
if [ -z "$DESTINATION" ]; then
    showHelp
    exit 1
fi

echo "$@"

#Run scp in the background with the remaining parameters.
$SCP $SCP_OPTS $@ $DESTINATION &

0

尝试对inode上的所有文件进行排序(查找/ mydir -type f -print | xargs ls -i | sort -n),然后使用cpio在ssh上传输它们。这样可以最大程度地利用磁盘,并使网络成为瓶颈。速度比跨网络快时难。


那是彻头彻尾的偷偷摸摸的:)
沃伦

我不能保证所有文件系统都能从中受益,这取决于inode布局的完成方式。
吉米·赫德曼

瓶颈在于每个TCP连接限制为320KB /秒。我想以并行TCP连接发送文件,以便获得320 * NumConnections,最高可达网络限制(约1200KB /秒)。按inode排序无法实现此目的。
ZimmyDubZongyZongDubby

什么限制了TCP速度?机器之间的路由器?
吉米·赫德曼

我的ISP。净中性?哈!
ZimmyDubZongyZongDubby

0

我知道一个可以分块传输文件的工具。该工具称为“ rtorrent”软件包/端口,可在两台主机上使用;)BitTorrent客户端通常在传输之前保留磁盘空间,并将块直接从套接字写入磁盘。此外,您将能够在漂亮的ncurses屏幕中查看所有传输的状态。

您可以创建简单的bash脚本来自动化“ * .torrent”文件的创建,然后将命令SSH到远程计算机,以便将其下载。这看起来有点难看,但是我认为如果不进行开发,您将找不到任何简单的解决方案:)


1
如果仅两台计算机参与文件传输,那么种子文件将如何提供帮助?洪流的想法是大量的播种者将数据提供给客户请求者。
DaveParillo

你是对的。但是谁说单个播种机没有用呢?;)
kolypto

2
如果洪流客户端与单个对等方创建多个TCP连接,则可以解决OP的问题。但是,我不知道torrent客户端是否确实与单个对等方建立了多个TCP连接。
chronos

0

FTP使用多个连接进行下载。如果您可以为VPN上的FTPSSH上的 FTP设置安全通道,则应该能够最大限度地利用网络链接。(请注意,通过SSH的FTP需要特别注意—请参阅链接。)

FTPS(基于SSL的FTP)也可以满足您的需求。

您也可以使用支持多个连接的SFTP客户端,但是我不确定SFTP是否支持单个文件的多个连接。这应该可以满足您大部分时间的需求,但是当您只需要传输一个大文件时,可能不会为您提供最大的吞吐量。


SFTP会更容易并且安全(如果不是更多的话)安全吗?
Mark Renouf

1
@rob:您从哪里获得“ FTP使用多个连接进行文件传输”的信息?有些客户端确实允许从FTP 下载多个流,但是绝对没有FTP客户端/服务器组合允许多个流上传到FTP。
chronos

@Mark:是的,SFTP可能会更容易且同样安全,但是我不知道它是否支持多个连接来传输单个文件。还是)感谢你的建议; 我将其添加到列表中。

1
@chronos:抱歉,目前还不清楚。我建议ZimmyDubZongyZongDubby使用FTP从CentOS服务器下载到FreeBSD客户端。我已经将答案更新为专门说“下载”而不是“文件传输”。
罗布

-1

解决方案1:我不确定这是否适合您的情况,但是您可以创建一个跨区的归档文件(例如,将tarfile分成多个块或一个跨度的7zip归档文件),然后使用rsync的多个实例将它们发送过来网络,然后在另一侧重新组装/提取它们。您可以编写一个通用脚本,其参数是要传输的目录和要使用的连接数。明显的缺点是,您双方都需要两倍的可用空间,并且在两端存档/提取文件时会产生额外的开销。

解决方案2:更好的解决方案是编写一个脚本或程序,该脚本或程序根据大小将大目录树分为多个子树,然后并行复制这些子树。如果先复制整个目录结构(不带文件),则可能会简化事情。


有人愿意详细说明下降投票吗?
罗布

-1

您是否在受信任的环境中运行两台计算机?您可以尝试netcat。在服务器端:

tar -czf - ./yourdir | nc -l 9999

并在客户端上:

nc your.server.net 9999 > yourdir.tar.gz

您可以让客户端连接使用ssh隧道:

ssh -f -L 23333:127.0.0.1:9999 foo@your.server.net sleep 10; \
    nc 127.0.0.1 23333 > yourdir.tar.gz

甚至整个分区都可以通过这种方式移动:

dd if=/dev/sda1 | gzip -9 | nc -l 9999

并在客户端上:

nc your.server.net 9999 > mysda1.img.gz

注意

netcat并不是目前最安全的传输工具,但是在正确的环境中它可能会很快,因为它的开销很低。

HowtoForge有一个很好的示例页面


这似乎是一个通用的答案,无法回答他的问题。我看不到您的任何解决方案将如何并行传输​​,据我所知,nc只是一个连接
davr

您可能是正确的,但是使用nc,您可以控制打开的端口。如果您愿意,可以指定10,000。
DaveParillo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.