What is cluster module?
The `cluster` module in Node.js allows you to create child processes (workers) that share server ports, enabling your application to take full advantage of multi-core systems and improve its robustness and scalability.
What is the `cluster` Module?
Node.js applications are single-threaded by default. While this simplifies concurrency, it means a single Node.js process cannot fully utilize all CPU cores available on a machine. The cluster module addresses this limitation by allowing a master process to fork multiple worker processes that can share the same server port.
Each worker process runs an independent instance of your application. When a request comes in, the operating system (or a load balancer) distributes it among the available worker processes.
Why Use `cluster`?
- Multi-core Utilization: Effectively uses all CPU cores on a server, leading to better performance for CPU-bound tasks.
- Improved Resilience: If one worker process crashes due to an unhandled error, other workers remain active, and the master process can fork a new worker to replace the failed one, preventing a complete application downtime.
- Scalability: Allows your application to handle a greater number of concurrent requests by distributing the load across multiple processes.
How It Works (Master-Worker Model)
The cluster module operates on a master-worker model:
- Master Process: This is the primary process that runs first. Its main responsibility is to create and manage worker processes. It typically doesn't handle client requests directly.
- Worker Processes: These are child processes forked by the master. Each worker runs a copy of the application code and can handle incoming requests independently. They share the same server port thanks to inter-process communication (IPC) with the master.
Example Usage
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
// Optional: Respawn the worker
cluster.fork();
});
} else {
// Workers can share any TCP connection
// In this case, it is an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Hello from worker ${process.pid} and served!\n`);
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
Key Properties and Events
cluster.isMaster(orcluster.isPrimaryfrom Node.js v15.0.0+): A boolean indicating if the current process is the master (primary) process.cluster.fork(): Used by the master to create a new worker process.cluster.workers: An object containing references to all active worker processes, indexed by their ID.cluster.on('exit', ...): Event emitted by the master when a worker process dies. Useful for logging or respawning workers.worker.on('message', ...)/worker.send(message): For inter-process communication (IPC) between master and workers.