从父进程派生/生成许多 Node.js 进程的最高性能方法

Ale*_*lls 5 fork pipe child-process node.js

我正在使用 Node.js 生成超过 100 个子进程,甚至可能是 1000 个。我担心的是,如果子进程的所有 stdout/stderr 都必须经过父进程,那么父进程可能会成为某种瓶颈。为了在某​​个地方登录。

所以我的假设是,为了实现最高的性能/吞吐量,我们应该忽略父进程中的 stdout/stderr,如下所示:

const cp = require('child_process');

items.forEach(function(exec){

   const n = cp.spawn('node', [exec], {
      stdio: ['ignore','ignore','ignore','ipc']
   });

});
Run Code Online (Sandbox Code Playgroud)

我的问题是,以这种方式使用管道会造成多少性能损失:

// (100+ items to iterate over)

items.forEach(function(exec){

   const n = cp.spawn('node', [exec], {
      stdio: ['ignore','pipe','pipe','ipc']
   });

});
Run Code Online (Sandbox Code Playgroud)

这样 stdout 和 stderr 通过管道传输到父进程?我认为性能损失可能会很大,特别是如果我们在父进程中处理 stdout/stderr ,如下所示:

     // (100+ items to iterate over)

    items.forEach(function(exec){

       const n = cp.spawn('node', [exec], {
          stdio: ['ignore','pipe','pipe','ipc']
       });

       n.stdout.setEncoding('utf8');
       n.stderr.setEncoding('utf8');

        n.stdout.on('data', function(d){
          // do something with the data
        });

        n.stderr.on('data', function(d){
          // do something with the data
        });

    });
Run Code Online (Sandbox Code Playgroud)

我假设

  1. 我假设如果我们在父进程中对 stdout 和 stderr 使用“忽略”,则这比将 stdout/stderr 管道传输到父进程的性能更高。
  2. 我假设如果我们选择一个文件来流式传输 stdout/stderr ,就像这样

    stdio: ['ignore', fs.openSync('/some/file.log'), fs.openSync('/some/file.log'),'ipc']

这几乎与对 stdout/stderr 使用“忽略”一样高效(应将 stdout/stderr 发送到 /dev/null)

这些假设正确与否?关于 stdout/stderr,如果我想将 stdout/stderr 记录到某处(而不是 /dev/null),如何才能实现最高性能?

注意:这是针对库的,因此 stdout/stderr 的数量可能会有很大差异。此外,很可能很少会派生比核心数量更多的进程,最多同时运行大约 15 个进程。

Joh*_*nck 1

这些假设正确与否?

我怎样才能达到最高的性能?

测试一下。这样您才能获得最高性能。在生产中使用的相同类型的系统上进行测试,具有相同数量的 CPU 和类似的磁盘(SSD 或 HDD)。

我认为您担心的是,如果父母阅读速度不够快,孩子可能会受阻。这是一个潜在的问题,具体取决于管道的缓冲区大小以及流经管道的数据量。但是,如果替代方案是让每个子进程独立写入磁盘,则这可能会更好、相同或更糟。我们不知道的原因有很多,首先我们不知道您有多少个内核、您的进程生成数据的速度以及您正在写入哪个 I/O 子系统。

如果您有一个 SSD,您可能能够每秒写入 500 MB。这很好,但如果 SSD 的大小为 512 GB,那么您只能坚持 16 分钟,然后就会被填满!在任何人都知道什么是最有效的方法之前,您需要进一步缩小问题范围。

如果您的目标只是以尽可能少的系统利用率从机器上获取记录的数据,那么最好的选择是直接将日志消息写入网络。