목요일, 6월 09, 2016

Node.js 프로세싱 모델

Node.js 프로세싱 모델
2016년 1월 4일 월요일
오후 5:38

  1. 문제
다음과 같이 5초간 대기하는 쿼리가 있고, 3명의 사용자가 이를 동시에 호출 한다고 했을 때, 과연 클라이언트의 응답시간은 어떻게 될까?

DB측 쿼리
-- wait for 1 second
WAITFOR DELAY '00:00:05' --> 5초가 대기
select * from hobby where userId=@userId


  1. 호출 시나리오 및 실행 결과
    1. Node.js 어플리케이션 호출은 다음과 같이 3개의 cmd 창을 띄어 curl 통해 node.js 호출 한다.

  1. Client 1


  1. Client 2


  1. Client 3


  1. 호출 결과
위 명령어를 거의 동시에 호출한다. 그리고 응답시간을 살펴보면 3 명령어가 거의 동시에 완료됨을 알 수 있다.


이때의, 서버 측 로그


많은 개발자들이, Node.js 기본적으로 단일 쓰레드로 동작한다고 알고 있어, 어플리케이션에 대기 또는 지연이 있는 경우, 요청이 직렬화 되어 전체 적으로 응답시간이 느려질 것으로 기대할 있는데, 사실 그렇지 않다.
다음 부분에서는, Node.js 프로세스 모델에 대해 살펴보고 Node.js 동작하는 방식을 이해해 보고자 한다.

  1. Node.js 이벤트 루프기반의 Single thread 모델과 동시 요청 처리의 이해
노드 Node.JS 단일 쓰레드가 아니다.
단일 쓰레드란 말은 Node.Js 이벤트 루프를 두고 하는 말이지, Node.Js 프로세스 모델이 그렇다는 것이 아니다.

Node.js는 다른 어플리케이션 서버처럼 요청과/응답을 처리할 , 다중 쓰레드로 처리하지 않고, 단일 쓰레드의 이벤트 루프 모델을 사용하여 이벤트 기반의 콜백 메커니즘활용하여 요청을 처리한다.

Node.js의 프로세스의 핵심은 "이벤트 루프"이며, Node.js 처리 방식을 알기 위해서는 이를 이해해야 하는데, 다음 처리단계를 통해 살펴본다.

단일 쓰레드 이벤트 루프 프로세스 단계
  1. Client node.js server 요청
  2. Node.js 서버는 client 요청을 처리하기 위해 내부적으로 제한된 thread pool 유지한다.
  1. Nodej.js 서버가 요청을 수신하고, 수신된 요청을 "Event Queue" 보관한다.
  1. Node.js 내부적으로 Event Loop라는 사용하고, Event loop 무한 루프를 돌며 큐를 검사한다
Event loop 단일 쓰레드로 동작한다.

  1. Event Queue 요청이 있다면, 다음과 같은 절차를 따른다.
    1. 큐에서 요청을 하나 꺼내와, 요청을 처리한다.
    2. 만약, 요청에 블러킹 I/O 없다면, 요청은 바로 처리되고 응답을 클라이언트로 반환한다.
    3. 반면, 요청에 DB, file system 또는, 외부 자원에 액세스하는 블러킹 i/o 요청 이라면, 다음의 작업을 진행한다.
  1. 내부 thread pool 가용 쓰레드가 있는지 점검
  2. 클라이언트 요청에 쓰레드 하나를 할당
  1. 해당 쓰레드는 블러킹 i/o 요청을 처리하고, 응답을 Event loop 보낸다.
  1. Event loop 응답을 요청했던 클라이언트로 다시 보낸다.


 다음은 Event loop 의사코드이다.
Event loop pseudo code


이와 같은 방식으로 프로세스가 동작되므로, 다수의 쓰레드 없이 최소의 쓰레드 만으로 높은 동시성을 제공한다고 있다.

Event Loop 기반의 싱글 쓰레드의 장점
  1. 동시에 많은 클라이언트 요청을 쉽게 처리한다.(다중 쓰레드 모델을 생각해보라.)
  1. 최소한의 쓰레드만을 사용하기 때문에 CPU, Memory 같은 리소스 또한 적게 소모한다.


위와 같은 프로세스 동작 메커니즘으로 인해, 높은 대기가 발생하는 DB 호출을 다룬다 해도 지연이 발생하지 않는데, 배후에는 Event Loop 있기에 가능하다.

하지만, 한계가 없는 것은 아니다.
내부 Thread pool 제한되어 있고,  Event Loop 여전히 싱글 쓰레드이기에 Event Queue 급격한 증가가 발생하여  탐색시간이 지연될 수 도 있으며 DB File system 같은 요청이 많아 지면 많아 질수록 지연을 불가피하다. 허나 이것은 모든 web app 서버가 가지고 있는 공통점 것이다.
그러므로특정 어플리케이션에서의 사전 벤치마킹을 통해 처리 임계 값을 파악하고 이를 주시하여 clustering 같은 적절한 확장이 필요하다.


하지만, 코드의 편의성과 높은 동시성은 Node.js만의 독보적인 장점인 것은 분명하다

댓글 없음: