Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many child processes can a node.js cluster spawn on a 64bit Wintel PC?

I was running a concurrency test, and for brevity's sake, defined a process for each spoofed http request. It worked fine for up to 64 requests/processes, but folded on 65. I'm running Window 7 (64bit) on an I5 laptop, with 4GB of Ram.

Whilst running the test I had a Chrome open (with a handful of tabs), and I expect that the OS' common system processes would also have some effect, but I know too little about node.js at the lowest level to understand where the problem lies.

For example, one article suggest it's possible to run well over 8000 processes on a 2GB 64-bit Windows XP system:

http://blogs.technet.com/b/markrussinovich/archive/2009/07/08/3261309.aspx

But the 64 child process figure that I ran into was rather conspicuous.

Any ideas?

like image 787
Charlie Avatar asked Dec 13 '22 05:12

Charlie


1 Answers

Well node is asynchronous, there's no blocking, only by the current script and it can handle multiple connections perfectly, so that means on a high concurrency, it would use all of your CPU, but each process can only use one core, since Node is not threaded. So technically what is recommend to have is having as many processes as your cores, one core for each process. In that case, on a high concurrency the Node cluster would use all of the CPU. If you go more than that, you are wasting your RAM and putting extra work on your OS scheduler. Beside that each nodejs process have an startup time. So it is very expensive to create a nodejs process at run time.

From Node.JS docs:

These child Nodes are still whole new instances of V8. Assume at least 30ms startup and 10mb memory for each new Node. That is, you cannot create many thousands of them.

Conclusion the best thing to do is to fork just as the number of your CPU cores, which is:

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker) {
    console.log('worker ' + worker.process.pid + ' died');
    cluster.fork();
  });
} else {
  // Worker processes have a http server.
  http.Server(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
}

We actually have a production server, doing that, which can take about 1000 concurrency, and less than 10ms latency serving the hello world.

like image 150
Farid Nouri Neshat Avatar answered May 01 '23 07:05

Farid Nouri Neshat