在两台服务器之间复制数百万个文件的最佳方法


39

我要复制到同一千兆网络中的另一台计算机上的单个目录中大约有500万个小文件(5-30k)。我尝试使用rsync,但是运行了几个小时后,它会减慢爬网速度,我认为由于rsync必须每次都要检查源文件和目标文件?

我的第二个想法是使用scp,但想征询外界的意见,看看是否有更好的方法。谢谢!


瓶颈可能是接收方的文件系统。放入单个目录中的文件越多,大多数文件系统最终将成倍地变慢(也就是说,每次rsync在接收方添加新文件时,接收方在传输的其余部分都会变慢)。许多较旧的文件系统在单个目录中甚至不能包含超过32K个文件。
Mikko Rantalainen

Answers:


41

这样的事情应该可以正常工作:

tar c some/dir | gzip - |  ssh host2 tar xz

由于您使用的是千兆位网络,因此也许还省略了gzip和“ z”标志以进行提取。


是否需要gzip压缩,或者ssh是否压缩流?还是可以做到的?
锡洛

1
如果传递“ -C”,ssh将压缩流。在局域网上,我不会为压缩流而烦恼。除非已经压缩,否则我可能会通过Internet进行访问。

6
就我个人而言,我会继续使用gzip:即使通过千兆以太网,瓶颈也不太可能是CPU。
本治十六世,

6
@BenjiXVI的瓶颈肯定是CPU,因为它gzip只能在单个内核上执行。您可以合理地预期默认压缩级别为6时大约为30 MB / s-但这不会使千兆位以太网最大化。
syneticon-dj

2
使用pbzip2?...
Apache

19

我敢肯定,您在一个目录中拥有所有五百万个文件的事实将使很多工具陷入困境。rsync不能很好地处理这一点我并不感到惊讶-这是一种“独特”的情况。如果您能找到一种将文件结构化为某种目录结构的方法,那么我相信标准同步工具(如rsync)将具有更高的响应速度。

但是,仅给出一些实际建议-也许一种解决方案是将驱动器物理上临时移动到目标计算机中,以便您可以在实际服务器中复制文件(而不是通过网络)。然后,将驱动器移回并使用rsync保持最新状态。


6
+1用于物理移动驱动器,这种方式的速度更快
罗伯特·古尔德

1
它肯定比复制跳动驱动器上的所有内容和来回走动
要好

@RobertGould让我们使用IPoAC作为我们的传输协议:“ D
coolcat007

12

要复制数百万个文件在千兆交换机(在一个信任的环境),你也可以使用的组合netcat (or nc)tar,如已经user55286建议。这会将所有文件作为一个大文件流式传输(请参阅快速文件复制-Linux!(39 GB))。

# requires netcat on both servers
nc -l -p 2342 | tar -C /target/dir -xzf -   # destination box
tar -cz /source/dir | nc Target_Box 2342    # source box

如今,随着越来越多的事情首先尝试IPv6,您可能还需要在两端使用带有nc命令的-4开关,以使其在“旧的” IPv4 LAN上运行。
BeowulfNode42 '22

5

目录中大约有100万个文件(大约4年的文件价值)。

然后我们使用robocopy将文件移动到YYYY / MM目录(每月大约35-45,000个文件)..我们将robocopy脚本放入.bat文件中,如下所示:

ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20081101 /MINAGE:20081201 /MOV H:\Cs\out\fix H:\BCK_REPORT\2008\11
ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20081201 /MINAGE:20090101 /MOV H:\Cs\out\fix H:\BCK_REPORT\2008\12
ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20090101 /MINAGE:20090201 /MOV H:\Cs\out\fix H:\BCK_REPORT\2009\01
ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20090201 /MINAGE:20090301 /MOV H:\Cs\out\fix H:\BCK_REPORT\2009\02

简要说明.. /ns /nc /nfl /np是为了避免使用其他信息使日志文件膨胀, /log+...是将摘要信息写入日志文件。

/minage and /maxage is to copy files modified with in that date range. 

因此,例如将文件修改为> = 01 / Nov / 2008(包括),将文件修改为<01 / Dec / 2008(不包括)

ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20081101 /MINAGE:20081201 /MOV H:\Cs\out\fix H:\BCK_REPORT\2008\11

/mov 移动文件

然后是源目录

然后是目标目录(目录将在需要时动态创建)。

价值1个月的转让(大约35-45,000个文件)花费了大约40-60分钟的时间。我们认为,价值1年的转让大约花费12个小时或更短的时间。

使用Windows Server 2003。

所有的东西都记录在日志文件中...开始时间,结束时间和复制的文件数。

Robocopy保存了这一天。


如今,robocopy具有/ MT [:n]开关,用于执行具有n个线程的多线程副本(默认为8),以达到更好的效果,并且不依赖日期范围,并且允许使用单个命令行而不是一个命令行每个线程。虽然MT开关无法使用在Windows 2003上
BeowulfNode42

4

您知道,我加了tar解决方案,但是-根据环境-还有另外一个想法发生。您可能会考虑使用dd(1)。诸如此类的速度问题在于,打开和关闭文件需要花费大量的头部动作,您需要执行500万次。在您可以确保这些分配连续的情况下,您可以改为dd,这样可以将头部运动的次数减少5倍或更多。


4

我更喜欢使用lz4作为目前最快的压缩工具。SSH选项-c arcfour128使用比默认更快的加密算法。[1]

因此目录传输类似于:

tar -c folder | lz4 -c | ssh -carcfour128 somehost 'lz4 -d | tar -x > folder'

请注意,在Debian lz4上的命令是lz4c,在CentOS上是lz4。


由于源或目标cpu上的cpu使用情况以及几乎所有ssh实现的单线程性质,ssh加密/解密可能会成为瓶颈。这是一个专用的千兆局域网,因此无需加密。
BeowulfNode42 '16

3

Robocopy非常适合这样的事情。它会在网络超时后重试,它还允许您设置数据包间的间隔延迟以现在淹没管道。

[编辑]

请注意,这是仅Windows应用程序。


假设您当然在窗户上。robocopy的优点是应用程序负责遍历文件。unixutils的问题在于,扩展名称可能会用完外壳空间。
马丁·贝克特

3

我知道这可能很愚蠢-但是您是否考虑过将它们复制到外部磁盘上并将其转移到另一台服务器上?它实际上可能是最有效,最简单的解决方案。


3

我们正在调查此问题。我们需要传输约1800万个小文件-总共约200GB。我们使用普通的旧XCopy实现了最佳性能,但是仍然花费了很长时间。从一台服务器到另一台服务器大约需要3天,到外部驱动器大约需要2周!

通过另一个过程,我们需要复制服务器。这是通过Acronis完成的。花了大约3个小时!!!

我们将对此进行更多调查。上面的dd建议可能会提供类似的结果。


2

已经提出了很多不错的建议,但想抛出Beyond Compare。最近,我通过千兆交换机将5KB至20MB之间的大约750,000个文件从一台服务器传输到了另一台服务器。它甚至根本没有打ic。虽然花了一段时间,但我希望有这么多数据。



1

在复制之前将它们打包到一个文件中,然后在复制后再次将其解压缩。


1

在类似的情况下,我尝试使用tar来批处理文件。我编写了一个小脚本,将tar命令的输出通过管道直接传递到目标计算机,再进入接收tar进程,该进程解开了文件。

与scp或rsync(YMMV)相比,tar方法几乎使传输速率增加了一倍。

这是tar命令。请注意,您需要通过在每台计算机的主目录中创建.rhosts文件来启用r命令(复制完成后将其删除-这是众所周知的安全问题)。还要注意,与往常一样,HP-UX很尴尬-而世界其他地方对于remote-shell命令使用'rsh',而HP-UX使用'remsh'。在HP看来,“ rsh”是某种受限制的外壳。

box1> cd source_directory; tar cf - . | remsh box2 "cd target_directory; tar xf - "

第一个tar命令创建一个名为“-”的文件,在这种情况下,这是一个特殊标记,表示“标准输出”。创建的存档包含当前目录(。)中的所有文件以及所有子目录(默认情况下tar是递归的)。该存档文件通过管道传递到remsh命令,该命令将其发送到box2计算机。在框2上,我首先转到正确的接收目录,然后从“-”或“标准输入”中提取传入的文件。

尽管我怀疑磁盘访问可能已成为限制因素,但我有6个tar命令同时运行以确保网络链接已充满数据。


1

绕过文件系统。

您是否可以卸载该分区以使文件驻留在该分区上,或者以只读方式安装该分区?这样做,然后类似:

dd if=/dev/PARTITION | ssh username@host "dd of=diskimage.bin"

然后,您可以将其diskimage.bin作为回送设备安装在目标侧,然后将文件复制到实际的目标文件系统中,或者使用适当的工具将其缝回到目标侧的空分区中(危险,但是可能,尽管我从未做过。)

如果您真的很勇敢,则可以dd直接将其放回目标端的分区中。我不建议那样。


0

您可以尝试以下操作(可能是成批处理的文件)

  • tar这批文件
  • gzip他们
  • 如果可能,使用scp复制
  • 拉链
  • 解压文件

0

如某人所建议,您可以在ssh上尝试使用tar。

如果您不需要加密(最初使用rsync,但没有提到它是rsync + ssh),则可以在netcat上尝试tar,以避免ssh开销。

当然,您也可以使用gzip或其他压缩方法来缩短时间。


0

还有其他事情要考虑。尝试这个:

  • 创建动态调整大小的VHD
  • 挂载它,可能作为目录
  • 设置“压缩整个磁盘”属性

这样,目录迭代或压缩不会产生任何开销,因为这是在写入文件时完成的。仅移动一个文件-VHD。

在Windows上,我将默认TCP数据包大小设置为较大,例如16348。这意味着IP标头开销较小。

不过,我遇到的一件事是,对于网络或USB传输,最好将文件大小保持在100 Mb以下。我使用Rar.exe来分割文件。

像冠军一样工作。这等效于Linux中的“ dd”。对于Linux,将压缩文件系统挂载到目录的概念也是正常的,因此适用相同的逻辑。与其他方法一样,您应确保在操作开始之前关闭所有文件。

这样做还有一个好处,就是可以在文件夹上放置大小配额。如果VHD是固定大小,超过该限制将不会导致服务器宕机,只会导致创建或写入文件时出错。

格式化为NTFS的VHD也可以处理一个文件夹中的数百万个文件。

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.