我们有一台存储服务器,目前大约有 20TB 的媒体文件,我们想将其与第二台存储服务器同步,以进行备份和故障转移。事实是:
- 我们目前存储了大约 900 万个文件
- 文件大小从几 KB 到 1 GB
- 仅需单向同步
- 文件不会更新,也不会删除——只需同步新文件
- 存储服务器正在运行 open-e,它们作为 NFS 卷安装在网络中
目前我们只在第三方服务器上使用普通 rsync 来执行同步。
我想知道,是否有更好的工具来处理如此大量的文件——商业的还是开源的?
非常感谢,
答案1
如果您只是使用手动脚本检查文件创建时间(可能还有大小)并将其与已同步到备份服务器的文件列表(或注册表)进行比较,您可能会看到性能的提升。
Rsync 可能会花费大量时间检查所有文件的更改,而检查一两个文件属性就足够了。
我们做了类似的事情,但规模要小得多,即在两台服务器之间同步照片。我编写了一个 bash 脚本,它维护一个按文件创建时间和文件大小连接在一起的已排序文件注册表。每次运行脚本时,它都会检查我们同步的服务器(源服务器),并生成一个按创建时间和文件大小连接在一起的已排序文件列表。然后我使用通信命令比较这两个注册表,并仅打印源服务器上出现的条目。这是必须同步到新服务器的文件列表。
然后我只需将新文件 scp 过来即可。我在其中设置了一些陷阱、锁定和限制,这样它就不会淹没所有内容,但它确实有效并且非常快。
好消息是,如果您已经在两个地方拥有大量文件,则无需同步所有内容。只需在目标服务器上创建一个初始注册表,然后按 cron 启动脚本,它就会从该点开始同步。如果您最终需要同步一个您从未想过的文件,您所要做的就是在源服务器上触摸它(更改日期信息),它将在下一次计划的运行时同步。
因此对于如下所示的目录:
-rw-r----- 1 example example 38801 2010-01-21 11:45 1.JPG
-rw-r----- 1 example example 38801 2010-01-21 11:45 2.JPG
-rw-r----- 1 example example 757638 2010-01-21 11:45 3.JPG
-rw-r----- 1 example example 16218 2010-01-22 15:07 9.JPG
该列表由脚本转换为如下所示的注册表文件:
1.JPG_2010-01-21_11:45_38801
2.JPG_2010-01-21_11:45_38801
3.JPG_2010-01-21_11:45_757638
9.JPG_2010-01-22_15:07_16218
我将该注册表(源服务器文件的注册表)存储在目标服务器上。每次在目标服务器上运行 cron 作业时,我都会使用相同格式创建当前源服务器上的文件列表。假设列表中出现了几个新文件,10.JPG 和 11.JPG。
-rw-r----- 1 example example 38801 2010-01-21 11:45 1.JPG
-rw-r----- 1 example example 38801 2010-01-21 11:45 2.JPG
-rw-r----- 1 example example 757638 2010-01-21 11:45 3.JPG
-rw-r----- 1 example example 16218 2010-01-22 15:07 9.JPG
-rw-r----- 1 example example 16218 2010-02-24 11:00 10.JPG
-rw-r----- 1 example example 16218 2010-02-24 11:00 11.JPG
当前文件注册表将如下所示:
1.JPG_2010-01-21_11:45_38801
2.JPG_2010-01-21_11:45_38801
3.JPG_2010-01-21_11:45_757638
9.JPG_2010-01-22_15:07_16218
10.JPG_2010_02_24_11:00_16218
11.JPG_2010_02_24_11:00_16218
跑步通信针对旧注册表和当前注册表并剪切出第一个字段(需要复制的文件),如下所示:
comm -23 ${CURRENT_REG} ${OLD_REG} | cut -d'_' -f1 > ${SYNC_LIST}
将产生需要复制(我使用 scp)到备份(目标)服务器的文件列表(每行一个):
10.JPG
11.JPG
然后您只需通过循环处理该文件列表。
这通信上面的命令基本上是说向我展示所有内容仅有的存在于第一个文件中。它进行的比较也非常快。毕竟它只是比较文本文件中的行;即使该文件非常大。幸运的是,您已经用一些有关文件的基本元数据填充了该文本文件,并且通过通信,正在快速比较这些数据。
将元数据填充到列表中的好处是,它可以允许文件有同步之间可能会发生更改。假设出现了文件的新版本,或者旧版本存在问题。文件的名称将存在于旧注册表中,但其元数据(文件创建时间戳和大小)将有所不同。因此,当前文件注册表将显示该差异,而通信比较会说该信息仅存在于第一个文件中。当您创建要复制的文件列表时,该文件名将在其中,并且您的复制命令将覆盖同名的过期文件。
其余的只是细节:
- 使用文件锁定/信号量,这样如果上次运行到下次运行还未完成,脚本就不会自行运行。
- 使用临时文件存储当前文件列表和进程列表,然后在脚本退出时使用陷阱清理它们。
- 完成所有操作后,将当前文件列表复制到旧文件列表上,为下一次比较做好准备,但只有当注册表中包含文件时才这样做(否则,您将复制一个空的注册表并在下次同步所有内容)。
希望对您有所帮助。这非常适合我们的情况,但与所有事情一样,在您的组织或设置的限制下可能无法正常工作。祝您好运,至少它可能会给您一些想法。