在我工作的一家公司,我们有一个叫做“播放列表”的东西,它是每个 ~100-300 字节的小文件。大约有一百万。每小时大约有 100,000 人换衣服。这些播放列表需要每小时上传到不同大陆的 10 个其他远程服务器,理想情况下需要在 2 分钟内快速完成。在主服务器上删除的文件也会在所有副本上删除,这一点非常重要。我们目前使用 Linux 作为我们的基础设施。
我正在考虑尝试使用 -W 选项的 rsync 来复制整个文件而不比较内容。我还没有尝试过,但也许对 rsync 有更多经验的人可以告诉我它是否是一个可行的选择?
还有哪些其他选择值得考虑?
更新:我选择 lsyncd 选项作为答案,但这只是因为它最受欢迎。其他建议的替代方案也以它们自己的方式有效。
由于即时更新也是可以接受的,您可以使用lsyncd。
它监视目录(inotify)并将
rsync
更改为从属。在启动时它会做一个 full
rsync
,所以这会花一些时间,但之后只会传输更改。递归监视目录是可能的,如果从属服务器关闭,将重试同步直到它恢复。
如果这一切都在一个目录(或目录的静态列表)中,您也可以使用incron。
缺点是它不允许递归查看文件夹,您需要自己实现同步功能。
考虑使用分布式文件系统,例如GlusterFS。在设计时考虑了复制和并行性,GlusterFS 可以比涉及 inotify 和
rsync
.对于这个特定的用例,可以构建一个包含 10 个副本的 10 服务器 GlusterFS 卷(即每个服务器 1 个副本/块),以便每个副本都是卷中每个其他副本的精确镜像。GlusterFS 会自动将文件系统更新传播到所有副本。
每个位置的客户端都会联系他们的本地服务器,因此对文件的读取访问会很快。关键问题是写入延迟是否可以保持在可接受的低水平。回答这个问题的唯一方法就是尝试一下。
我怀疑
rsync
是否会以正常方式为此工作,因为扫描一百万个文件并将其与远程系统进行 10 次比较会花费很长时间。我会尝试用类似的东西实现一个系统,该系统inotify
保留修改文件的列表并将它们推送到远程服务器(如果这些更改无论如何都没有以其他方式记录)。然后,您可以使用此列表快速识别需要传输的文件——甚至可能使用 rsync(或更好的 10 个并行实例)。编辑:通过一些工作,您甚至可以使用这种 inotify/log watch 方法在修改发生后立即复制文件。
一些更多的选择:
这似乎是MongoDB和GridFS的理想故事书用例。由于文件相对较小,MongoDB 本身就足够了,尽管使用 GridFS API 可能更方便。
MongoDB 是一个 nosql 数据库,而 GridFS 是一个建立在它之上的文件存储。MongoDB 有很多用于复制和分片的内置选项,因此它应该在您的用例中很好地扩展。
在您的情况下,您可能会从一个副本集开始,该副本集由位于您的主数据中心的主服务器(可能是第二个,以防您希望在同一位置进行故障转移)和分布在世界各地的十个“奴隶”组成。然后进行负载测试以检查写入性能是否足够并检查节点的复制时间。如果您需要更多性能,您可以将设置变成一个分片(主要是将写入负载分配到更多服务器)。MongoDB 被设计为使用“廉价”硬件扩展大型设置,因此您可以投入一批廉价服务器来提高性能。
我会使用 S3 后端,然后将其安装在我需要的所有服务器上——这样一来,每个人都会立即同步
似乎尚未提及的一个选项是将所有文件归档到一个压缩文件中。这应该会显着减少总大小,并消除处理数百万个单独文件的所有开销。通过在一次大更新中替换整个文件集,您还可以放心,删除的文件会在副本上删除。
缺点当然是您正在不必要地传输许多文件。由于压缩,这可能会或可能不会被减小的尺寸所平衡。我也不知道压缩那么多文件需要多长时间。