我们的内联网上有一个文件夹结构,其中包含大约 800,000 个文件,分布在大约 4,000 个文件夹中。我们需要将其同步到 DMZ 中的一小群机器。该结构的深度非常浅(深度不会超过两层)。
大多数文件永远不会改变,每天有几千个更新文件和 1-2 千个新文件。数据是历史报告数据,其中源数据已被清除(即这些是最终报告,其源数据足够旧,我们将其存档并删除)。每天同步一次就足够了,因为它可以在合理的时间范围内完成。报告是在夜间生成的,我们会在早上第一时间同步,这是一项计划任务。
显然,由于定期更改的文件很少,增量复制对我们有很大帮助。我们尝试过 Rsync,但这可能要花很长时间八至十二小时只是为了完成“构建文件列表”操作。很明显,我们的增长速度已经超出了 rsync 的能力范围(12 小时的时间太长了)。
我们一直在使用另一个名为 RepliWeb 的工具来同步结构,它可以在大约 45 分钟内完成增量传输。然而,我们似乎已经超出了它的极限,它开始看到文件显示为已删除,但实际上并非如此(也许某些内部内存结构已经耗尽,我们不确定)。
有其他人遇到过这种大规模同步项目吗?是否有专门用于处理这种大规模文件结构的同步项目?
答案1
如果您可以信任文件系统的最后修改时间戳,则可以将 Rsync 与 UNIX/Linux 的“find”实用程序结合使用来加快速度。“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
将从当前目录(“。”)开始并递归遍历所有子目录,查找:
- 任何目录(“-type d”),
- 命名为“.svn”(“-name'.svn'”),
- 包含过去 24 小时内修改的元数据(“-ctime -0”)。
它会在标准输出上打印符合这些条件的任何内容的完整路径名(“-print”)。选项“-name”、“-type”和“-ctime”称为“测试”,选项“-print”称为“操作”。'find' 的手册页有完整的测试和操作列表。
如果您真的想聪明一点,可以使用“find”命令的“-cnewer”测试,而不是“-ctime”,以使此过程更具容错性和灵活性。“-cnewer”测试树中的每个文件/目录的元数据是否比某些参考文件更近被修改。在每次运行开始时,在“find... | rsync...”命令执行之前,使用“touch”创建下一个运行的参考文件。以下是基本实现:
#!/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 小时的情况。
答案2
尝试齐奏,它是专门为解决这个问题而设计的,通过将更改列表(构建文件列表)保存到每个服务器本地,加快计算增量的时间,并减少之后通过网络发送的数量。
答案3
如果您在 rsync 上使用 -z 开关,请尝试不使用它。出于某种原因,我发现这甚至可以加快文件的初始枚举速度。
答案4
从 rsync 命令中去掉 -z(不压缩)可以让“接收文件列表”运行得更快,我们只需要传输大约 500 GB 的文件。之前使用 -z 开关需要一天时间。