在 4 台机器上复制小文件的最快方法?

在 4 台机器上复制小文件的最快方法?

我有 4 台服务器,全部位于安全的本地网络上。

每个服务器运行 script.php(每分钟)。

script.php 从名为 /arc 的本地目录读取,执行文件测试,并将新文件写回 /arc。

(这些是 2kb 的小型文本文件,每台服务器以每秒大约 20 个的速度创建)。

我希望将所有 4 个 /arc 目录合并为一个。

例如,当 script.php 在 server1 上运行时,我希望它知道所有 /arc 目录中的所有文件,而不仅仅是本地计算机上的文件。当 server1 将文件写入其本地 /arc 目录时,servers2-4 现在必须在其 /arc 目录中看到它。

还值得注意的是,这些文件极易腐坏,每 10 分钟就会被清理一次。

更新:目前,我将尝试 NFS 挂载所有目录。arc 目录也是 tmpfs,因此应该相当快。除非有人认为有更快的方法,否则我将尝试以下方法:

1) 在每台机器上,我将通过 NFS 将 /arc 目录挂载到所有其他机器。因此,1 个本地机器和 3 个 NFS 机器。

2) 当 script.php 在任何一台机器上运行时,每个 arc 目录都会有多个“cp”命令。这将确保每台机器始终具有最新的缓存输出。(每秒 20 个副本 X NFS 上的 4 个位置会成为瓶颈吗?我希望不是。)

3) 由于缓存的输出被复制到所有本地机器,这意味着 script.php 永远不需要通过 NFS 挂载读取文件。本地读取 arc 缓存需要 0.37 秒。通过 NFS 读取文件需要多长时间?比这更长?如果我复制到一个中心位置,就会发生这种情况。

因此,我用多个复制命令来换取读取命令。但我认为这是一笔不错的交易,因为关键是要让 script.php 请求尽可能快地运行,这意味着最大限度地减少读取缓存文件所需的时间。

答案1

rsync 专为 1 个源和 1 个目标之间的单向同步而设计。它不适合 4 个主机之间的可靠双向同步。

SyncThing 或 BitTorrent Sync 等同步工具可能会起作用,尽管文件的变化率(20/秒)对于这些工具来说可能太快了。

我的建议是指定其中一台服务器作为“主服务器”(或者,设置第五台机器或 NAS),并将/arc所有其他机器的网络挂载(例如 NFS)到该主服务器,以便每台机器上的脚本实际上都在同一个目录中工作。

如果您不能接受对托管目录的单台机器的依赖,那么另一种选择是使用 DRBD 之类的东西来创建可以通过网络在块级别进行复制的分布式块设备。

答案2

每秒 20 个 2k 文件... 在 4 台机器上。这听起来你真正想要的是数据库服务器。

MySQL、Postgres、SQLServer 都可以轻松处理该更新率。

如果每台机器都需要复制到其他 3 台机器,那么每个文件就需要 n-1 份副本。因此,4 台机器每秒生成 20 个文件,即每秒 120 份副本。如果您需要第 5 台机器,则数量会翻倍。第 6 台机器会再翻倍。您可能认为未来不会增长,但事实确实如此。

scp如果在创建每个文件后访问它们,则scp每次运行 script.php 时都会有 3 条命令。考虑到 scp 验证会话所需的时间,每次运行可能需要 1-2 秒。即scp每秒 60 秒。

相反,您可以只创建文件并让另一个进程rsync循环运行。每次运行时,rsync 都会获取任何新文件。从创建文件到将其发送到其他服务器之间的时间可能是几秒或几分钟。如果您想备份数据并能在发生意外中断时承受一些数据丢失,那么这样做是可以的。但如果您希望其他服务器立即获得信息,这还不够。

另一方面,如果你使用数据库,所有 3 台机器都会缓存与数据库的连接,更新会非常快。数据将立即可用。

答案3

如果您可以很好地控制服务器,那么我认为围绕 RabbitMQ 之类的消息服务器进行构建可能是可行的方法。您无需创建文件,而是将消息放入队列,然后您的脚本订阅这些队列事件,进行处理,然后将结果放回到队列中以供其他服务器获取。

我认为 rsync 不是可行的方法。 lsync的模型可能很有趣,因为它监视内核事件的变化,但它是一种主/从安排,我不确定它是否适合您的情况。

您可能更适合使用某种共享网络文件系统,正如@Andy 所建议的那样。(NFS、GFS、Gluster)浮现在脑海中,还有更多。不过要小心锁定问题,以及如果与文件服务器的连接中断会发生什么。

@TomOnTime 的回复可能是正确的,因为他说基于文件的系统可能是错误的选择。基于 SQL 的解决方案的主要优点是您可能已经设置了数据库服务器。不过,在 SQL 中使这类事情变得高效时,陷阱比您想象的要多。

编辑:

如果您说这是一个缓存系统,那么您可能还想看看 memcached、redis 甚至 varnish。

您的应用程序是否提前知道它们期望缓存中的内容而不需要询问列表?

相关内容