在局域网上复制大文件的快速方法

ixt*_*lix 30 networking nfs file-copy tcp

我在使用 NFS 时遇到了一些问题,我想尝试仅使用普通的旧 TCP。

不过,我不知道从哪里开始。

在硬件方面,我使用以太网交叉电缆连接两台上网本。

为了联网它们,我输入

$ sudo ifconfig eth0 192.168.1.1 up && ping -c 10 -s 10 192.168.1.2 && sudo /etc/init.d/nfs-kernel-server start
Run Code Online (Sandbox Code Playgroud)

在第一台上网本和

$ sudo ifconfig eth0 192.168.1.2 up
$ ping -c 10 -s 10 192.168.1.1
$ mount /mnt/network1
Run Code Online (Sandbox Code Playgroud)

在第二

其中/mnt/network1在 /etc/fstab 中指定为

192.168.1.1:/home /mnt/network1 nfs noauto,user,exec,soft,nfsvers=2 0 0

以及/etc/exports(使用该文件的语法),在第一台上网本上。

以上工作正常,但文件和目录很大。这些文件平均每块大约半 GB,目录大小都在 15 到 50 GB 之间。

我正在rsync用来传输它们,命令(上192.168.1.2)是

$ rsync -avxS /mnt/network1 ~/somedir
Run Code Online (Sandbox Code Playgroud)

我不确定是否有办法调整我的 NFS 设置以更好地处理大文件,但我想看看rsync在普通旧 TCP 上运行守护程序是否比rsync在 NFS 上运行更好。

那么,重申一下,我如何使用 TCP 设置类似的网络?

更新:

所以,经过几个小时的努力,我想把自己从无知的泥潭中拉出来(或者,我喜欢这样想,靠自己的引导把自己拉起来),我想出了一些有用的事实。

但首先,是什么让我走上了这条兔子之路,而不是简单地接受当前的最佳答案:这nc是一个令人难以置信的酷程序,它坚决不适合我。我试过netcat-openbsdnetcat-traditional包,但没有任何运气。

我在接收机器 ( 192.168.1.2)上遇到的错误是:

me@netbook:~$ nc -q 1 -l -p 32934 | tar xv
Can't grab 0.0.0.0:32934 with bind
tar: This does not look like a tar archive
tar: Exiting with failure status due to previous errors
Run Code Online (Sandbox Code Playgroud)

route 给出:

me@netbook:~$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         dir-615         0.0.0.0         UG    0      0        0 wlan0
link-local      *               255.255.0.0     U     1000   0        0 eth0
192.168.0.0     *               255.255.255.0   U     2      0        0 wlan0
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
Run Code Online (Sandbox Code Playgroud)

但是,好消息是:将静态 IP 地址设置在 中/etc/network/interfaces,我在尝试开始工作时开始这样做nc,解决了我所有的 NFS 问题并重新点燃了我对 NFS 的热爱。

我使用的确切配置(192.168.1.1当然是第一台上网本)是:

auto eth0
iface eth0 inet static
address 192.168.1.2
netmask 255.255.255.0
Run Code Online (Sandbox Code Playgroud)

通过这些设置,两台上网本在开机后就可以直接互相ping通,甚至不需要ifup.

无论如何,我仍然很想看到nc实际情况,所以我希望有人帮助我调试这个过程。

der*_*ert 51

快捷方式

通过 LAN 传输文件的最快方法可能不是 rsync,除非更改很少。rsync 花费相当多的时间进行校验和计算,计算差异等。如果您知道无论如何您都将传输大部分数据,只需执行以下操作(注意:有多种实现netcat;请查看手册以了解正确的选项。特别是,您可能不想要-p):

user@dest:/target$ nc -q 1 -l -p 1234 | tar xv

user@source:/source$ tar cv . | nc -q 1 dest-ip 1234
Run Code Online (Sandbox Code Playgroud)

它使用 netcat ( nc) 通过端口 1234 上的原始 TCP 连接发送 tar。没有加密、真实性检查等,因此速度非常快。如果您的交叉连接以千兆或更低的速度运行,您将固定网络;如果它更多,您将固定磁盘(除非您有存储阵列或快速磁盘)。vtar的标志使它在运行时打印文件名(详细模式)。对于大文件,这几乎没有开销。如果你正在处理大量的小文件,你会关掉它。此外,您可以pv在管道中插入类似的内容以获得进度指示器:

user@dest:/target$ nc -q 1 -l -p 1234 | pv -pterb -s 100G | tar xv
Run Code Online (Sandbox Code Playgroud)

当然,您也可以插入其他内容,例如gzip -1(并z在接收端添加标志——z当然,除非您设置 GZIP 环境变量,否则发送端的标志将使用比 1 更高的压缩级别)。尽管 gzip 实际上可能会更慢,除非您的数据真的被压缩了。

如果你真的需要 rsync

如果您真的只传输一小部分已更改的数据,rsync 可能会更快。您可能还想查看-W/--whole-file选项,因为使用速度非常快的网络(如交叉连接)可以更快。

运行 rsync 的最简单方法是通过 ssh。您需要尝试使用 ssh 密码来查看哪个最快,它将是 AES、ChaCha20 或 Blowfish(尽管 Blowfish 的 64 位块大小存在一些安全问题),具体取决于您的芯片是否具有英特尔的 AES -NI 指令(以及您的 OpenSSL 使用它们)。在足够新的 ssh 上,rsync-over-ssh 如下所示:

user@source:~$ rsync -e 'ssh -c aes128-gcm@openssh.com' -avP /source/ user@dest-ip:/target
Run Code Online (Sandbox Code Playgroud)

对于较旧的 ssh/sshd,请尝试aes128-ctraes128-cbc代替aes128-gcm@openssh.com.

ChaCha20 将是chacha20-poly1305@openssh.com(还需要一个足够新的 ssh/sshd)和 Blowfish 将是河豚-cbc。OpenSSH 不允许在没有密码的情况下运行。您当然可以使用您喜欢的任何 rsync 选项来代替-avP. 当然,您可以走另一个方向,从目标机器(拉)而不是源机器(推)运行 rsync。

使 rsync 更快

如果您运行 rsync 守护程序,则可以摆脱加密开销。首先,您将创建一个守护程序配置文件 ( /etc/rsyncd.conf),例如在源计算机上(阅读 rsyncd.conf 联机帮助页了解详细信息):

[big-archive]
    path = /source
    read only = yes
    uid = someuser
    gid = somegroup
Run Code Online (Sandbox Code Playgroud)

然后,在目标机器上,您将运行:

user@dest:~$ rsync -avP source-ip::big-archive/ /target
Run Code Online (Sandbox Code Playgroud)

您也可以反过来执行此操作(但当然您需要将只读设置为否)。有身份验证等选项,请查看联机帮助页了解详细信息。

  • 这是一个很好的答案。另一个也很棒。难道仅仅因为提问者不能在它们之间做出选择就没有被接受的答案吗? (2认同)

bah*_*mat 21

如何?或 TL;DR

我发现最快的方法是组合tar,mbufferssh

例如:

tar zcf - bigfile.m4p | mbuffer -s 1K -m 512 | ssh otherhost "tar zxf -"
Run Code Online (Sandbox Code Playgroud)

使用它,我在 1Gb 链接上实现了超过 950 Mb/s 的持续本地网络传输。替换每个 tar 命令中的路径以适合您要传输的内容。

为什么?缓冲!

到目前为止,通过网络传输大文件的最大瓶颈是磁盘 I/O。答案是mbufferbuffer。它们在很大程度上相似,但mbuffer具有一些优点。默认缓冲区大小为 2MBmbuffer和 1MB buffer。较大的缓冲区更有可能永远不会为空。选择目标文件系统和目标文件系统上本地块大小的最小公倍数的块大小将提供最佳性能。

缓冲是让一切变得不同的东西!有的话就用吧!如果你没有它,得到它!使用(m}?bufferplus 任何东西都比任何东西本身都好。它几乎是解决慢速网络文件传输的灵丹妙药。

如果您要传输多个文件,请使用tar将它们“合并”到一个数据流中。如果它是单个文件,您可以使用cat或 I/O 重定向。tarvs.的开销在cat统计上是微不足道的,所以我总是使用tar(或zfs -send在我可以的地方),除非它已经是一个tarball。这些都不能保证为您提供元数据(特别是cat不会)。如果您需要元数据,我会将其留给您作为练习。

最后,ssh用于传输机制既安全又带来很少的开销。同样,sshvs nc.的开销在统计上是微不足道的。

  • i7-3770 上的“openssl speed”为河豚 CBC 提供了约 126-146 MB/秒,为 AES CBC 提供了约 138-157 MB/秒(该芯片具有 AES-NI 指令)。然后对于 sha256,大约为 200–300 MB/秒。所以它只能勉强推动 1 Gb。使用 OpenSSH 6.1+,您可以使用 AES GCM,它可以以致盲率(370–1320 MB/秒,取决于消息大小)执行此操作。所以我认为只有当你在带有 AES-NI 的芯片上运行 6.1+ 并使用 AES-GCM 时,OpenSSH 的开销很小。 (4认同)
  • 由于 mbuffer 的参数化,我收到一个致命错误: 'mbuffer: fatal: total memory must be large than block size \n Terminated' 。为了更正,我怀疑它应该读取类似“mbuffer -s 1K -m 512M”的内容,最后的“M”代表 MByte(来源:man mbuffer) (2认同)