Node.js 跨多个磁盘驱动器的文件系统 I/O 性能:工作线程与否?

Node.js performance in file system I/O across multiple disk drives: worker threads or not?

我在这里 questions and 阅读了一些关于 Node.js 以非阻塞方式快速高效地处理文件 I/O 操作与使用工作线程相比的性能优势阻塞或非阻塞请求,但是 none 似乎回答了我的问题。

我正在编写一个 Node.js 应用程序,它将打开、散列和写入存储在多个硬盘驱动器上的非常大的文件(多个演出)。我正在探索工作线程的想法,因为它们允许我将命令隔离到特定的硬盘驱动器。例如:假设我有一个线程处理将硬盘 A 上的一个文件复制到硬盘 B,另一个线程处理将一个文件从硬盘 C 复制到硬盘 D。

假设我同时将它扩展到更多的硬盘驱动器,我只使用 Node.js 没有工作线程并让它处理所有这些请求是否更有意义,或者工作线程如果我可以按驱动器隔离 I/O 并同时处理多个驱动器的请求,会更有意义吗?

根据我的阅读,工作线程似乎是显而易见的解决方案,但我也看到让单个 Node.js 进程处理文件队列 I/O 通常更快.感谢您提供的任何指导!

编辑: 显然(根据下面的评论),nodejs 只有一个线程池在所有工作线程之间共享。如果是这种情况,那么为每个磁盘获得一个单独的池的唯一方法是使用多个进程,而不是多个线程。

或者,您可以扩大工作池,然后制作自己的排队系统,一次只将对每个单独磁盘的几个请求放入工作池,从而在不同的驱动器之间提供更多的并行性。

原回答(部分仍然适用):

没有工作线程,您将有一个 libuv 线程池来处理所有磁盘 I/O 请求。因此,它们都将进入同一个池,一旦该池中的线程繁忙(无论它们正在服务哪个磁盘),新请求将按照它们到达的顺序排队。这可能不太理想,因为如果您对驱动器 A 有 5 个请求,对驱动器 B 有 1 个请求,对驱动器 C 有 1 个请求,您不希望首先用对驱动器 A 的 5 个请求填充池,因为这将使驱动器 B 和驱动器 C 的请求等到驱动器 A 上的多个请求完成后才能开始。这失去了一些跨单独驱动器的并行性的机会。当然,您是否真正在单独的驱动器上获得并行性还取决于驱动器控制器的实现以及它们是否真的具有单独的 SATA 控制器。

如果你确实使用了工作线程,每个磁盘一个nodejs工作线程,你至少可以保证每个磁盘的线程池中有一个单独的OS线程池,你可以做到更有可能的是,没有一组针对一个驱动器的请求会阻止对其他驱动器的请求有机会开始并错过与对其他驱动器的请求并行 运行 的机会。

现在,当然,所有这些讨论都是理论上的。在磁盘驱动器、控制器卡、控制器之上的操作系统以及 libuv 和 nodejs 之上的控制器的世界中,理论讨论有很多机会无法在现实世界的测量中得到证实。

因此,真正确定的唯一方法是实施工作线程选项,然后将其与具有几种不同磁盘使用情况的非工作线程选项进行基准比较,包括您认为可能最糟糕的几种情况案件。因此,与任何与性能相关的重要问题一样,您将不可避免地必须进行基准测试和衡量才能确定其中一种方式。而且,您的结果也需要非常仔细地构建基准测试才能发挥最大作用。

只是为了扩展每个进程模型,它看起来与 jfriend00 建议的工作线程相同,只是 IPC 机制发生了变化。

从“头”管理器进程管理作业队列,并将 drive/hashing 工作拆分为每个工作人员的节点进程,因此每个工作人员中没有 IO/CPU 争用。

让每个工作人员一次从其驱动器(或驱动器组)的工作队列中选择一个作业。您所需要的只是可靠性、监控未处理的工作人员以及工作人员 completion/errors.

的 return 通道

排队机制并不重要,数据库 table 就足够了(或任何类型的网络消息传递 http、grpc、nanomsg、redis、nats、rabbitmq)。这是基于不需要在经理和工人之间共享大量数据,除了简单的工作消息“嘿工人,这是一个文件去处理它”,“我完成了这个文件”或“我打破了,帮助!"

| Manager                        |
| Pub 1 2 3                      |
| Sub 1    | Sub 2    | Sub 3    |
| Worker   | Worker   | Worker   |
|          |          |          |
| DriveA   | DriveC   | DriveE   |
| DriveB   | DriveD   | DriveF   |

运行 如果进程最终 CPU 绑定,则每个核心一个工作人员,或者管理 IO 要求所需的数量。随着您添加驱动器或更多服务器,工作人员可以轻松扩展。