cluster

김무연·2023년 12월 13일

Backend

목록 보기
30/49
post-thumbnail

cluster

기본적으로 싱글 스레드인 노드가 CPU 코어를 모두 사용할 수 있게 해주는 모듈

  • 포트를 공유하는 노드 프로세스를 여러 개 둘 수 있음
  • 요청이 많이 들어왔을 때 병렬로 실행된 서버의 개수만큼 요청이 분산됨
  • 서버에 무리가 덜 감
  • 코어가 8개인 서버가 있을 때: 보통은 코어 하나만 활용
  • cluster로 코어 하나당 노드 프로세스 하나를 배정 가능
  • 성능이 8배가 되는 것은 아니지만 개선됨
  • 단점: 컴퓨터 자원(메모리, 세션 등) 공유 못 함,

    예를 들면 로그인을 할 시 한 서버에서 로그인 인증이 남아있지만, 다른 서버에는 공유가 안됨, 따라서 클라이언트가 접속할 때 8개의 서버중 랜덤으로 접속하기 때문에 로그인이 풀리거나 할 수 있음

  • Redis 등 별도 서버로 해결

서버 클러스터링

마스터 프로세스와 워커 프로세스

  • 마스터 프로세스는 CPU 개수만큼 워커 프로세스를 만듬 (worker threads랑 구조 비슷)
  • 워커 스레즈는 스레드를 여러개 만든 것이고, 클러스터는 프로세스를 여러개 만드는 것
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`마스터 프로세스 아이디: ${process.pid}`);
  // CPU 개수만큼 워커를 생산
  for (let i = 0; i < numCPUs; i += 1) {
    cluster.fork();
  }
  // 워커가 종료되었을 때
  cluster.on('exit', (worker, code, signal) => {
    console.log(`${worker.process.pid}번 워커가 종료되었습니다.`);
    console.log('code', code, 'signal', signal);
    cluster.fork();
  });
} else {
  // 워커들이 포트에서 대기
  http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
    res.write('<h1>Hello Node!</h1>');
    res.end('<p>Hello Cluster!</p>');
    setTimeout(() => { // 워커 존재를 확인하기 위해 1초마다 강제 종료
      process.exit(1);
    }, 1000);
  }).listen(8086);

  console.log(`${process.pid}번 워커 실행`);
}

const numCPUs = require('os').cpus().length 로 내 컴퓨터의 cpu개수를 구한 후

if (cluster.isMaster) {
  console.log(`마스터 프로세스 아이디: ${process.pid}`);
  // CPU 개수만큼 워커를 생산
  for (let i = 0; i < numCPUs; i += 1) {
    cluster.fork();
  }

부모 클러스터에서 워커를 생산하게 됨, 이후 라운드 로빈 알고리즘에 따라 부모 클러스터에서 자식 클러스터 서버로 요청을 분배해 줌

cluster.fork() 로 워커가 죽을 때마다 새로운 워커를 생성할 수 있음

    console.log(`${worker.process.pid}번 워커가 종료되었습니다.`);
    console.log('code', code, 'signal', signal);
    cluster.fork();
  • 이 방식은 좋지 않음
  • 오류 자체를 해결하지 않는 한 계속 문제가 발생
  • 하지만 서버가 종료되는 현상을 막을 수 있어 참고할 만함.
profile
Notion에 정리된 공부한 글을 옮겨오는 중입니다... (진행중)

0개의 댓글