Node.js 멀티코어 활용을 위한 Cluster 모듈 도입기
문제 상황
EC2 인스턴스(c5.xlarge, 4코어)에서 Node.js API 서버를 운영 중이었는데, CPU 사용률이 25%를 넘지 않았다. 부하 테스트를 돌려봐도 동일했다. Node.js는 싱글 스레드 기반이라 단일 프로세스만으로는 멀티코어를 제대로 활용하지 못한다는 것을 간과했었다.
Cluster 모듈 적용
Node.js 내장 Cluster 모듈을 사용해 CPU 코어 수만큼 워커 프로세스를 생성하도록 변경했다.
const cluster = require('cluster');
const os = require('os');
const express = require('express');
if (cluster.isMaster) {
const numCPUs = os.cpus().length;
console.log(`Master process ${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 {
const app = express();
// ... 기존 Express 설정
app.listen(3000, () => {
console.log(`Worker ${process.pid} started`);
});
}
결과
- CPU 사용률: 평균 25% → 80% (부하 시)
- 초당 요청 처리량: 약 3배 증가
- 응답 시간: 95 percentile 기준 40% 개선
주의사항
워커 프로세스 간 메모리는 공유되지 않는다. 세션 정보 같은 상태는 Redis 등 외부 스토어를 사용해야 한다. 우리는 이미 Redis를 세션 스토어로 사용 중이어서 별도 작업은 불필요했다.
PM2 같은 프로세스 매니저를 쓰면 Cluster 모드를 더 쉽게 관리할 수 있지만, 일단은 직접 구현해서 동작 방식을 이해하는 것이 우선이라고 판단했다.