同步非常大的文件夹结构


14

我们的Intranet上有一个文件夹结构,其中包含大约800,000个文件,分为大约4,000个文件夹。我们需要将其同步到DMZ中的小型计算机集群。结构的深度很浅(从不超过两个深度)。

大多数文件永远不会改变,每天都有几千个更新文件和1-2 000个新文件。数据是在已清除源数据的地方维护的历史报告数据(即,这些是最终报告,其源数据足够旧,我们可以将其存档和删除)。鉴于每天同步一次可以在合理的时间范围内进行,因此每天同步一次就足够了。报告是在一夜之间生成的,我们将早晨的第一件事作为计划任务同步。

显然,由于很少有文件定期更改,因此我们可以从增量复制中受益匪浅。我们已经尝试过Rsync,但是仅完成“构建文件列表”操作就可能需要八到十二个小时。显然,我们正在迅速超越rsync的功能(12小时的时间框架太长了)。

我们一直在使用另一个名为RepliWeb的工具来同步结构,它可以在大约45分钟内进行增量传输。但是,似乎我们已经超过了它的极限,它开始看到文件在没有删除时显示为删除(也许某些内部存储器结构已经用完,我们不确定)。

还有其他人遇到过这种大规模的同步项目吗?是否有设计用于处理此类大型文件结构以进行同步的工具?


您是否尝试过将工作同时分散在多个rsync实例上进行拆分?我对目录结构没有真正的了解,但是可以按目录名或文件名将其拆分。
离合器

我们曾考虑过这一点,但是由于结构如此平坦,很难找到用于分割工作的良好分界线。文件夹在很大程度上的命名非常相似,这使情况变得复杂(存在一个命名约定,该约定使大多数文件夹以相同的初始6个字符集开头)。
MightyE 2010年

戴夫,您找到一个好的解决方案了吗?我正在考虑将lsyncd用于具有65535个子目录的目录,每个子目录可能具有65 ^ 16个文件。
Mike Diehn 2014年

1
@MikeDiehn我从未在这里找到我完全满意的工具。我们获得了专有的RepliWeb工具来修复该错误,即他们将文件视为删除而并非删除,这是一个溢出的内部结构。多年前我离开了那份工作,我想他们仍在使用那份工作。对于您的目的,如果目录合理分布,则可以使用Ryan解决方案之类的方法。它不会注意到顶级删除,但是65535子目录向我暗示您可能没有这些删除。
MightyE 2014年

Answers:


9

如果您可以信任文件系统上次修改的时间戳,则可以通过将Rsync与UNIX / Linux“查找”实用程序结合使用来加快处理速度。'find'可以汇编显示过去一天中最后修改时间的所有文件的列表,然后仅将缩短的文件/目录列表通过管道传送到Rsync。这比让Rsync将发件人上的每个文件的元数据与远程服务器进行比较要快得多。

简而言之,以下命令将仅在最近24小时内已更改的文件和目录列表上执行Rsync:(Rsync不会费心检查任何其他文件/目录。)

find /local/data/path/ -mindepth 1 -ctime -0 -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.

如果您对'find'命令不熟悉,它将通过特定的目录子树递归,查找符合您指定条件的文件和/或目录。例如,此命令:

find . -name '\.svn' -type d -ctime -0 -print

将从当前目录(“。”)开始,并遍历所有子目录,查找:

  • 任何目录(“ -d型”),
  • 名为“ .svn”(“-name'.svn'”),
  • 最近24小时内修改过的元数据(“ -ctime -0”)。

它在标准输出上打印符合这些条件的所有内容的完整路径名(“ -print”)。选项“ -name”,“-type”和“ -ctime”称为“测试”,选项“ -print”称为“动作”。“查找”的手册页包含测试和操作的完整列表。

如果您想变得真正聪明,可以使用'find'命令的'-cnewer'测试,而不是'-ctime',以使此过程更具容错性和灵活性。'-cnewer'测试树中的每个文件/目录是否都比某些参考文件更新了其元数据。在每次运行开始时,在“查找...”之前,使用“触摸”创建下一个运行的参考文件。rsync ...”命令执行。这是基本的实现:

#!/bin/sh
curr_ref_file=`ls /var/run/last_rsync_run.*`
next_ref_file="/var/run/last_rsync_run.$RANDOM"
touch $next_ref_file
find /local/data/path/ -mindepth 1 -cnewer $curr_ref_file -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.
rm -f $curr_ref_file

该脚本会自动知道上次运行的时间,并且仅传输自上次运行以来修改的文件。尽管这比较复杂,但是它可以保护您避免因停机或其他错误而错过了超过24小时的运行时间。


这是一个非常聪明的解决方案!我在想你touch $next_ref_file到底要不要?但是,这的确使我们无法处理已删除的路径(即使这些静态存档报告最终变得足够老,也无法归档和删除)。但这可能不是表演的制胜法宝。
MightyE

我发现尽管find . -ctime 0在此目录结构上速度仍然很慢(仍在等待它完成以报告其时间)。这实际上使我不满意,因为这似乎是一个相当低级的操作,可能为我们期望完成此工作的最快速度设置了标准。磁盘I / O可能是此处的限制因素。
MightyE

至于那个脚本,是的,我犯了一个错误。我的意思是在运行“查找...”之前立即在“ next_ref_file”(不是“ curr_ref_file”)上运行“ touch”。rsync ...”命令。(我将解决问题的答案。)
Ryan B. Lynch

3
至于慢速的“查找”命令:您正在使用哪种文件系统?如果使用的是Ext3,则可能需要考虑两个FS调整:1)运行'tune2fs -O dir_index <DEVICE_NODE>'以启用Ext3的'dir_index'功能,以加快对具有大文件数量的目录的访问。2)运行“ mount -o remount,noatime,nodiratime”以关闭访问时间更新,这通常会加快读取速度。'dumpe2fs -h <DEVICE_NODE> | grep dir_index'告诉您是否已启用'dir_index'(在某些发行版中,这是默认设置),以及'mount | grep <DEVICE_NODE>'告诉您有关访问时间的更新。
瑞安·林奇

遗憾的是,NTFS-Windows 2003 Server使用Cygwin作为find命令。我会记得ext3的那些调整选项(出色的建议),以防万一我们在我们的Debian集群之一上遇到类似的情况。
MightyE 2010年

7

尝试统一,它是专门为解决此问题而设计的,方法是将更改列表(构建文件列表)保留在每个服务器本地,加快计算增量的时间,并减少以后通过网络发送的数量。


我正在尝试Unison。在“寻找更改”阶段,它已经运行了大约2个小时,根据它当前正在处理的文件,它似乎已经完成了一半(因此,开始传输之前总共需要4个小时)。看起来它会比rsync更好,但是仍然超出了我们期望的操作范围。
MightyE

2
首次在双方上创建索引时,重建时间与rsync相似,因为它必须对每个文件进行哈希处理。完成此操作后,统一将使用目录的最后修改时间来确定文件何时更改,而仅需扫描该文件以查找更改。
戴夫·切尼

不幸的是,我是一名过度热情的Operations管理员的受害者,他在目录完成之前就强制结束了我的会话(我们限制了同时登录生产服务器的次数)。我失去了建立初始目录所取得的进展,因此我必须重新开始。我会让你知道怎么回事。
MightyE

现在,初始目录已构建以扫描更改,大约需要2个小时。我很惊讶Unison为此使用了多少RAM。对于我们的文件收集,源服务器使用的是635M,远程客户端使用的是366M。要同步集群中的多台计算机,将需要大量资源,尤其是对于源服务器而言!
MightyE 2010年

1
您是否能够以一种易于识别最近更改的数据的方式来构造数据?即,以年/月/日/ ...格式存储它?
戴夫·切尼


2

如果您正在rsync上使用-z开关,请尝试在没有它的情况下运行。出于某种原因,我看到它甚至可以加快文件的初始枚举的速度。


我们尝试使用-z标志和不使用-z标志。它似乎对“构建文件列表”的执行时间没有影响。
MightyE

2

从不进行压缩的rsync命令中删除-z,可以使“接收文件列表”的运行速度大大提高,因此我们不得不传输约500 GB。使用-z开关花了一天的时间。

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.