Node.js 클러스터 이해하기: 기본 개념
Grace Collins
Solutions Engineer · Leapcell

서문
PM2를 사용하여 Node.js 프로세스를 관리한 적이 있다면 클러스터 모드를 지원하는 것을 알 수 있습니다. 이 모드를 사용하면 Node.js가 여러 프로세스를 생성할 수 있습니다. 클러스터 모드에서 인스턴스 수를 최대로 설정하면 PM2는 서버에서 사용 가능한 CPU 코어 수에 해당하는 Node 프로세스 수를 자동으로 생성합니다.
PM2는 Node.js의 클러스터 모듈을 활용하여 이를 달성합니다. 이 모듈은 Node.js의 단일 스레드 특성을 해결하여 전통적으로 여러 CPU 코어를 활용하는 능력을 제한합니다. 그러나 클러스터 모듈은 내부적으로 어떻게 작동할까요? 프로세스들은 어떻게 서로 통신할까요? 여러 프로세스가 동일한 포트에서 어떻게 수신할 수 있을까요? 그리고 Node.js는 이러한 프로세스에 어떻게 요청을 분배할까요? 이러한 질문이 궁금하시다면 계속 읽어보세요.
핵심 원칙
Node.js 작업자 프로세스는 child_process.fork()
메서드를 사용하여 생성됩니다. 즉, 하나의 부모 프로세스와 여러 자식 프로세스가 있습니다. 코드는 일반적으로 다음과 같습니다.
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { for (let i = 0, n = os.cpus().length; i < n; i++) { cluster.fork(); } } else { // 애플리케이션 시작 }
운영 체제를 공부했다면 fork()
시스템 호출에 익숙할 것입니다. 호출 프로세스는 부모이고 새로 생성된 프로세스는 자식입니다. 이러한 자식 프로세스는 부모와 동일한 데이터 세그먼트와 스택을 공유하지만 물리적 메모리 공간이 반드시 공유되는 것은 아닙니다. Node.js 클러스터에서 마스터 프로세스는 포트에서 수신하고 들어오는 요청을 작업자 프로세스에 분배합니다. 여기에는 프로세스 간 통신(IPC), 로드 밸런싱 전략 및 다중 프로세스 포트 수신이라는 세 가지 핵심 주제를 다루는 것이 포함됩니다.
프로세스 간 통신 (IPC)
마스터 프로세스는 process.fork()
를 사용하여 자식 프로세스를 생성합니다. 이러한 프로세스 간의 통신은 IPC 채널을 통해 처리됩니다. 운영 체제는 다음과 같은 프로세스 간 통신을 위한 여러 메커니즘을 제공합니다.
-
공유 메모리 여러 프로세스가 단일 메모리 공간을 공유하며 종종 동기화 및 상호 배제를 위해 세마포어로 관리됩니다.
-
메시지 전달 프로세스는 메시지를 보내고 받음으로써 데이터를 교환합니다.
-
세마포어 세마포어는 시스템에서 할당한 상태 값입니다. 제어 기능이 없는 프로세스는 특정 검문소에서 강제로 중단되어 신호를 기다립니다. 이진 값 (0 또는 1)으로 제한되는 경우이 메커니즘을 "뮤텍스" (상호 배제 잠금)라고합니다.
-
파이프 파이프는 두 프로세스를 연결하여 한 프로세스의 출력이 다른 프로세스의 입력으로 사용될 수 있도록 합니다. 이는
pipe
시스템 호출을 사용하여 생성할 수 있습니다. 셸 스크립팅의|
명령은 이 메커니즘의 일반적인 예입니다.
Node.js는 부모와 자식 프로세스 간의 통신을 위해 이벤트 기반 메커니즘을 사용합니다. 다음은 부모 프로세스가 TCP 서버 핸들을 자식 프로세스로 보내는 예입니다.
const subprocess = require('child_process').fork('subprocess.js'); // 서버를 생성하고 핸들을 보냅니다. const server = require('net').createServer(); server.on('connection', (socket) => { socket.end('Handled by the parent process'); }); server.listen(1337, () => { subprocess.send('server', server); }); process.on('message', (m, server) => { if (m === 'server') { server.on('connection', (socket) => { socket.end('Handled by the child process'); }); } });
로드 밸런싱 전략
앞서 언급했듯이 모든 요청은 마스터 프로세스에 의해 분배됩니다. 서버 로드가 작업자 프로세스 간에 균등하게 분배되도록 하려면 로드 밸런싱 전략이 필요합니다. Node.js는 기본적으로 라운드 로빈 알고리즘을 사용합니다.
라운드 로빈
라운드 로빈 방식은 Nginx에서도 사용되는 일반적인 로드 밸런싱 알고리즘입니다. 첫 번째 프로세스부터 시작하여 마지막 프로세스에 도달한 후 다시 루프를 돌면서 들어오는 요청을 각 프로세스에 순차적으로 분배하는 방식으로 작동합니다. 그러나 이 방법은 모든 프로세스에서 동일한 처리 용량을 가정합니다. 요청 처리 시간이 크게 다른 시나리오에서는 로드 불균형이 발생할 수 있습니다.
이를 해결하기 위해 Nginx는 종종 **가중 라운드 로빈(WRR)**을 사용합니다. 여기서 서버에는 서로 다른 가중치가 할당됩니다. 가중치가 가장 높은 서버는 가중치가 0으로 줄어들 때까지 선택되고, 그 시점에서 새 가중치 시퀀스에 따라 사이클이 다시 시작됩니다.
NODE_CLUSTER_SCHED_POLICY
환경 변수를 설정하거나 cluster.setupMaster(options)
를 통해 구성하여 Node.js에서 로드 밸런싱 전략을 조정할 수 있습니다. 다중 시스템 클러스터에는 Nginx를 사용하고 단일 시스템 다중 프로세스 밸런싱에는 Node.js 클러스터를 결합하는 것이 일반적인 접근 방식입니다.
다중 프로세스 포트 수신
초기 버전의 Node.js에서는 동일한 포트에서 수신하는 여러 프로세스가 들어오는 연결을 위해 경쟁하여 고르지 않은 로드 분배가 발생했습니다. 이는 나중에 라운드 로빈 전략으로 해결되었습니다. 현재 접근 방식은 다음과 같이 작동합니다.
- 마스터프로세스는 소켓을 생성하고 주소에 바인딩하여 수신을 시작합니다.
- 소켓의 파일 디스크립터(fd)는 작업자 프로세스에 전달되지 않습니다.
- 마스터 프로세스가 새 연결을 수락하면 연결을 처리해야 하는 작업자 프로세스를 결정하고 그에 따라 전달합니다.
본질적으로 마스터 프로세스는 포트에서 수신하고 정의된 전략(예: 라운드 로빈)을 사용하여 작업자 프로세스에 연결을 분배합니다. 이 디자인은 작업자 간의 경쟁을 제거하지만 마스터 프로세스가 매우 안정적이어야 합니다.
결론
PM2의 클러스터 모드를 시작점으로 하여 이 기사에서는 다중 프로세스 애플리케이션을 구현하기 위한 Node.js의 클러스터 모듈의 핵심 원리를 살펴보았습니다. 프로세스 간 통신, 로드 밸런싱 및 다중 프로세스 포트 수신이라는 세 가지 주요 측면에 중점을 두었습니다.
클러스터 모듈을 연구함으로써 많은 기본 원리와 알고리즘이 보편적임을 알 수 있습니다. 예를 들어 라운드 로빈 알고리즘은 운영 체제 프로세스 스케줄링과 서버 로드 밸런싱 모두에서 사용됩니다. 마스터-워커 아키텍처는 Nginx의 다중 프로세스 설계와 유사합니다. 마찬가지로 세마포어 및 파이프와 같은 메커니즘은 다양한 프로그래밍 패러다임에서 널리 사용됩니다.
새로운 기술이 계속 등장하지만 그 기반은 일관성을 유지합니다. 이러한 핵심 개념을 이해하면 자신감을 가지고 새로운 과제를 추론하고 적응할 수 있습니다.
Leapcell은 Node.js 프로젝트를 클라우드에 배포하기 위한 최고의 선택입니다.
Leapcell은 웹 호스팅, 비동기 작업 및 Redis를 위한 차세대 서버리스 플랫폼입니다.
다국어 지원
- Node.js, Python, Go 또는 Rust로 개발하십시오.
무제한 프로젝트를 무료로 배포
- 사용량에 대해서만 지불하십시오 — 요청 없음, 요금 없음.
탁월한 비용 효율성
- 유휴 요금 없이 사용한 만큼만 지불하세요.
- 예: 평균 응답 시간 60ms에서 25달러로 694만 건의 요청을 지원합니다.
간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
손쉬운 확장성 및 고성능
- 쉬운 고 동시성을 처리하기 위해 자동 확장합니다.
- 운영 오버헤드가 전혀 없으므로 구축에만 집중하십시오.
설명서에서 더 많은 내용을 살펴보세요!
X에서 팔로우하세요: @LeapcellHQ