同步存储服务器

同步存储服务器

我们有一台存储服务器,目前大约有 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

然后您只需通过循环处理该文件列表。

通信上面的命令基本上是说向我展示所有内容仅有的存在于第一个文件中。它进行的比较也非常快。毕竟它只是比较文本文件中的行;即使该文件非常大。幸运的是,您已经用一些有关文件的基本元数据填充了该文本文件,并且通过通信,正在快速比较这些数据。

将元数据填充到列表中的好处是,它可以允许文件同步之间可能会发生更改。假设出现了文件的新版本,或者旧版本存在问题。文件的名称将存在于旧注册表中,但其元数据(文件创建时间戳和大小)将有所不同。因此,当前文件注册表将显示该差异,而通信比较会说该信息仅存在于第一个文件中。当您创建要复制的文件列表时,该文件名将在其中,并且您的复制命令将覆盖同名的过期文件。

其余的只是细节:

  • 使用文件锁定/信号量,这样如果上次运行到下次运行还未完成,脚本就不会自行运行。
  • 使用临时文件存储当前文件列表和进程列表,然后在脚本退出时使用陷阱清理它们。
  • 完成所有操作后,将当前文件列表复制到旧文件列表上,为下一次比较做好准备,但只有当注册表中包含文件时才这样做(否则,您将复制一个空的注册表并在下次同步所有内容)。

希望对您有所帮助。这非常适合我们的情况,但与所有事情一样,在您的组织或设置的限制下可能无法正常工作。祝您好运,至少它可能会给您一些想法。

答案2

这里有几个可以考虑的选项。

调查数据库如果您不需要同时访问两个副本。这是由于文件系统限制而不是 DBRD 的限制,并且存在一些解决方法如果需要,可以访问第二个副本。但该项目最近被纳入内核,因此今后对该项目的支持应该相当简单。

另一个选择是文件系统,例如集群文件系统. 可以设置 2 个节点复制配置。我认为这是理想的,因为它应该能够实现更好的故障转移和可扩展性。MondoDB 也对使用其 GridFS 的这类东西感兴趣,但它有点新。

相关内容