从父进程派生/产生许多node.js进程的最高性能方式

我正在使用Node.js产生100个以上的subprocess,甚至1000个。我担心的是父进程可能会成为某种瓶颈,如果所有的subprocess的stdout / stderr必须通过父进程为了得到login的地方。

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

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

我的问题是,以这种方式使用pipe道会有多大的性能损失:

 // (100+ items to iterate over) items.forEach(function(exec){ const n = cp.spawn('node', [exec], { stdio: ['ignore','pipe','pipe','ipc'] }); }); 

这样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 }); }); 

我假设

  1. 我假设我们在父进程中对stdout和stderr使用“ignore”,这比pipe道stdout / stderr对父进程的性能要高。
  2. 我假设如果我们select一个文件来streamstdout / stderr像这样

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

这几乎和使用stdout / stderr的“忽略”一样(应该把stdout / stderr发送到/ dev / null)

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

注意:这是为了一个库,所以stdout / stderr的数量可能会有所不同。 此外,很可能很less会分叉更多的进程比核心,最多同时运行约15个进程。

这些假设是否正确?

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

testing它。 这就是你可以实现最高性能的方法。 testing您将在生产中使用的相同types的系统,具有相同数量的CPU和类似的磁盘(SSD或HDD)。

我假设你担心的是,如果家长读得不够快,孩子可能会被阻止。 这是一个潜在的问题,取决于pipe道的缓冲区大小以及通过它的数据stream量。 但是,如果替代方法是让每个subprocess独立写入磁盘,则可能会更好,相同或更糟糕。 我们不知道一大堆原因,首先是我们不知道你有多less内核,你的进程产生数据的速度以及你写的I / O子系统。

如果你有一个单一的SSD,你可能会写每秒500 MB。 这太棒了,但是如果SSD的容量是512GB,那么只有16分钟才能满满! 在任何人都知道什么是最有效的方法之前,你需要缩小问题范围。

如果您的目标仅仅是尽可能less的系统利用率从机器上获取logging的数据,那么最好的办法就是直接将日志消息写入networking。

您有以下select:

  • 你可以让subprocess完全忽略stdout / stderr,并通过任何其他方式自己进行日志logging(logging到文件,syslog …)

  • 如果你正在logging父进程的输出,你可以分别设置stdout / stderr为process.stdoutprocess.stderr 。 这意味着孩子的输出将与主要过程相同。 没有什么会stream过主stream程

  • 你可以直接设置文件描述符。 这意味着subprocess的输出将会转到给定的文件,而不经过父进程

  • 然而,如果你没有任何控制subprocess,你需要以某种方式对日志做些什么(过滤它们,在关联的subprocess等前缀),那么你可能需要通过父进程。

由于我们不知道您所谈论的日志量,所以我们不知道这是关键还是过早优化。 Node.js是asynchronous的,我不希望你的父进程成为瓶颈,除非它真的很忙,你有很多的日志。