스레드 풀(Thread Pool)과 워커 스레드(Worker Thread)
Node.js는 본질적으로 싱글 스레드 기반의 이벤트 루프 모델을 채택하고 있지만, 내부적으로 멀티 스레드를 활용하여 비동기 I/O와 CPU 집약적인 작업을 효율적으로 처리할 수 있도록 설계되어 있습니다. Node.js에서 멀티 스레드를 사용하는 방식은 크게 두 가지로 나뉩니다: 스레드 풀 (Thread Pool) 과 워커 스레드 (Worker Threads)입니다.
스레드 풀 (Thread Pool)
Node.js가 특정 작업을 수행할 때 자동으로 멀티 스레드를 사용하는 대표적인 메커니즘이 바로 스레드 풀입니다. 이는 Node.js 내부에서 사용하는 libuv 라이브러리를 통해 구현되어 있으며, 비동기 I/O 작업이나 일부 CPU 연산을 백그라운드에서 처리할 수 있도록 지원합니다.
스레드 풀은 주로 다음과 같은 작업에서 사용됩니다.
- 파일 시스템 I/O (fs.readFile(), fs.writeFile() 등)
- 암호화 연산 (crypto.pbkdf2(), crypto.scrypt())
- 압축 작업 (zlib 모듈)
- DNS 조회 (dns.lookup())
이러한 API를 호출할 경우, Node.js는 메인 스레드에서 이벤트 루프를 막지 않고, 백그라운드 스레드 풀 중 하나에 작업을 위임합니다. 작업이 완료되면, 결과는 이벤트 루프를 통해 콜백으로 전달됩니다. 이 방식은 Node.js의 논블로킹 I/O를 가능하게 하는 핵심 요소입니다.
기본적으로 Node.js의 스레드 풀은 4개의 스레드로 구성되어 있으며, 이는 UV_THREADPOOL_SIZE 환경 변수를 통해 최대 128개까지 확장할 수 있습니다. 다만, 모든 스레드 풀 사용 API가 이 스레드를 공유하기 때문에, 고부하 상황에서 병목이 발생할 수 있으며, 이 경우 스레드 수를 조절하는 것이 필요할 수 있습니다.
스레드 풀의 작동 순서는 다음과 같습니다.
- 이벤트 루프가 블로킹 또는 지연이 예상되는 작업을 감지합니다.
- 해당 작업이 libuv의 스레드 풀 중 하나에 할당됩니다.
- 스레드에서 작업이 완료되면, 완료 이벤트가 다시 이벤트 루프에 전달되고 콜백이 실행됩니다.
워커 스레드 (Worker Threads)
스레드 풀이 Node.js 내부에서 자동으로 사용하는 방식이라면, 워커 스레드는 개발자가 명시적으로 생성하고 제어할 수 있는 멀티 스레드입니다. worker_threads 모듈을 통해 제공되며, Node.js v10.5.0부터 실험적으로 도입되었고 v12 LTS부터 안정화되었습니다.
워커 스레드는 주로 다음과 같은 상황에서 사용됩니다.
- 독립된 실행 환경 – 각 워커는 별도의 V8 인스턴스와 자체 이벤트 루프를 가지므로, 메인 스레드와 격리되어 실행됩니다.
- 통신 방식 – 워커 스레드와 메인 스레드는 메시지 기반 통신 (postMessage)이나 SharedArrayBuffer를 통한 공유 메모리로 데이터를 주고받을 수 있습니다.
- 명시적인 제어 – 개발자가 직접 워커를 생성하고, 종료 시점을 관리하며, 메시지 핸들링을 구현해야 합니다.
결론
Node.js는 기본적으로 단일 스레드 모델이지만, libuv를 통한 스레드 풀과 worker_threads 모듈을 통해 멀티 스레드를 유연하게 활용할 수 있습니다. 이 두 가지 메커니즘을 잘 이해하고 적절히 사용하는 것은 성능 최적화와 병목 제거에 핵심적인 역할을 합니다.
스레드 풀은 대부분의 I/O 작업에서 자동으로 활용되기 때문에, 이를 조절하려면 작업 특성에 따라 UV_THREADPOOL_SIZE를 설정해주는 것이 중요합니다. 반면, 워커 스레드는 명시적인 제어가 필요한 CPU 집약 연산에 적합하며, 특히 동시성(concurrency)이 중요한 시스템에서는 매우 유용한 도구입니다.
Node.js의 비동기 실행 모델과 스레드 활용 방식은 고성능 서버 애플리케이션을 구축하기 위한 핵심 기초입니다. 이를 이해함으로써 우리는 더 예측 가능하고, 더 빠르고, 더 안정적인 Node.js 기반 애플리케이션을 만들 수 있습니다.
'Project > Node.js' 카테고리의 다른 글
내가 아는 Node.js -3 (0) | 2025.05.28 |
---|---|
내가 아는 Node.js -2 (0) | 2025.05.28 |
내가 아는 Node.js -1 (0) | 2025.05.28 |
Node.js 시스템에서 비동기 대기 처리(Queueing)의 필요성 (0) | 2025.05.23 |
Node.js의 GC(Garbage Collection) (1) | 2025.05.23 |