Cluster and Fork mode difference in PM2
Asked Answered
M

3

137

I've searched a lot to figure out this question, but I didn't get clear explanation. Is there only one difference thing that clustered app can be scaled out and forked app cannot be?

PM2's public site explains Cluster mode can do these feature but no one says about pros of Fork mode (maybe, it can get NODE_APP_INSTANCE variable).

I feel like Cluster might be part of Fork because Fork seems like to be used in general. So, I guess Fork means just 'forked process' from the point of PM2 and Cluster means 'forked process that is able to be scaled out'. Then, why should I use Fork mode?

Motivity answered 8/1, 2016 at 16:47 Comment(0)
J
168

The main difference between fork_mode and cluster_mode is that it orders pm2 to use either the child_process.fork api or the cluster api.

What does this means internally?

Fork mode

Take the fork mode as a basic process spawning. This allows to change the exec_interpreter, so that you can run a php or a python server with pm2. Yes, the exec_interpreter is the "command" used to start the child process. By default, pm2 will use node so that pm2 start server.js will do something like:

require('child_process').spawn('node', ['server.js'])

This mode is very useful because it enables a lot of possibilities. For example, you could launch multiple servers on pre-established ports which will then be load-balanced by HAProxy or Nginx.

Cluster mode

The cluster will only work with node as it's exec_interpreter because it will access to the nodejs cluster module (eg: isMaster, fork methods etc.). This is great for zero-configuration process management because the process will automatically be forked in multiple instances. For example pm2 start -i 4 server.js will launch 4 instances of server.js and let the cluster module handle load balancing.

Jorgensen answered 23/3, 2016 at 11:42 Comment(3)
question based on your answer here: I have a use case I need to have, say 30 instances of my node.js app spawned with a unique, predefined, port number ( :3000 through :3030 ) and have each of the instances handle a specific group of users who will only access on their assigned port. So I dont want the Master process to do load balancing, but rather, only start (and keep running) the child processes. Is this possible? Or will it attempt to spread the load out across all the spawned child processes only?Sepulture
I'd use pm2 programatic API to launch 30 processes in fork_mode and use something else as a load balancer between the 30 ports. You may also use pm2 start -i 30 app.js and let the nodejs cluster do the work.Jorgensen
note: in cluster mode the master process is a single point of failure.Penzance
N
59

Node.js is single-thread.

That means only 1 core of your Intel quad-core CPU can execute the node application.

It called: fork_mode.

We use it for local dev.

pm2 start server.js -i 0 helps you running 1 node thread on each core of your CPU.

And auto-load-balance the stateless coming requests.

On the same port.

We call it: cluster_mode.

Which is used for the sake of performance on production.

You may also choose to do this on local dev if you want to stress test your PC :)

Nisse answered 15/2, 2016 at 15:16 Comment(4)
thaks, it clears lots of thing in my mind about nodejsKweilin
great explanation !!Perissodactyl
Node.js is not single threaded, there is (currently) one userland thread but it is certainly backed by a libuv threadpool.Racon
@BenjaminGruenbaum Agree with you. My statement should be understood in the assumption that I'm not mentioning too deeply down to libuv levelNisse
P
19

Documentation and sources are really misleading here.

Reading up on this in the sources, the only differences seems to be, that they use either node cluster or child_process API. Since cluster uses the latter, you are actually doing the same. There is just a lot more custom stdio passing around happening inn fork_mode. Also cluster can only be communicated with via strings, not objects.

By default you are using fork_mode. If you pass the the -i [number]-option, you're going into cluster_mode, which you generally aim for w/ pm2.

Also fork_mode instance probably can't listen on the same port due to EADDRINUSE. cluster_mode can. This way you also can structure you app to run on the same port being automatically load balanced. You have to build apps without state then though e.g. sessions, dbs.

Palestra answered 8/1, 2016 at 23:22 Comment(5)
I'm still confused. cluster built-in module uses child_process internally? and your suggestion is if I need flexible stdio, I have to use Fork-mode?Motivity
THe stdio thing is something of pm2's implementation. Don't worry about this. You want to use cluster_mode in production because it's hardening your instance since it's running -i [number] instances in the background. Use fork_mode if hardening is not necessary or you want better logs and stuff.Palestra
Also obviously cluster_mode uses more resources of your system because you are running -i [number] processes.Palestra
Although I warmly appreciated your answer, I didn't catch the point even now. Most of your explanation are kind of natural things (e.g. CLI usage of cluster_mode, load-balance of cluster_mode, cluster_mode uses more resources..). That's the reason why I haven't voted. Could you explain both simple use cases? Each case has to have be reasonable why it took its mode.Motivity
@Palestra Can you explain more about "You have to build apps without state then though e.g. sessions, dbs."? Why the app should be without state?Brucine

© 2022 - 2024 — McMap. All rights reserved.