Node.js 클러스터 모드로 멀티코어 활용하기

문제 상황

서버 CPU 사용률을 모니터링하던 중 4코어 서버에서 단일 코어만 100%를 찍는 걸 발견했다. Node.js가 단일 스레드로 동작하기 때문에 당연한 현상이지만, 나머지 3개 코어가 놀고 있는 건 명백한 자원 낭비였다.

클러스터 모드 구현

Node.js의 cluster 모듈을 사용해 워커 프로세스를 생성했다.

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

if (cluster.isMaster) {
  console.log(`Master ${process.pid} is running`);
  
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  
  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
    cluster.fork(); // 죽은 워커 재시작
  });
} else {
  require('./app'); // Express 앱 실행
  console.log(`Worker ${process.pid} started`);
}

주의사항

워커 프로세스 간 메모리는 공유되지 않는다. 세션 데이터를 메모리에 저장하던 방식에서 Redis로 변경해야 했다.

const session = require('express-session');
const RedisStore = require('connect-redis')(session);

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: 'your-secret',
  resave: false,
  saveUninitialized: false
}));

결과

4개 워커 프로세스가 고르게 부하를 분산하면서 전체 CPU 사용률이 평준화됐다. 동시 처리량은 약 3배 향상됐고, 한 워커가 크래시해도 다른 워커가 요청을 처리하면서 가용성도 개선됐다.

PM2 같은 프로세스 매니저를 쓰면 더 편하겠지만, 직접 구현하면서 내부 동작 원리를 이해할 수 있었다.