본문 바로가기

node.js (OctoberSkyJs)

왜 Node.js 인가?

함께 스터디에 참여하고 계신 이병주(@PillarLee)님이 올려주신 번역글입니다.
http://yambbam.kr/docs/why-node.js-single-thread-event-loop-javascript.html
위 주소에도 올리셨는데, 무료계정이라 트래픽이 작아 어찌될지 모르겠다고 제 블로그에 올려서 함께 보자 하셔서 옮겨 올립니다. 병주님과 함께 문장을 다듬기로 했습니다만, 현재 원문 링크 사이트가 깨져서 문장 다듬기는 진행하지 못했습니다. 조금 거칠더라도 양해해 주세요. :D



왜 Node 인가?

이벤트 중심인 Node.js 또는 Node는 프로그래머가 Evetned, non-blocking I/O 주도 접근법을 사용하여 웹 어플리케이선의 코드를 작성할 수 있게 해준다.  Node는 구글의 엄청나게 빠른 V8 자바스크립트 엔진을 기반으로 만들어졌다. 이 자바스크립트 엔진은 매우 빠른 동적 프로퍼티 접근머신코드의 동적 생성고효율 가비지 컬렉션으로 잘 알려져 있다.  이 자바스크립트 엔진은 Node.js가 끔찍하게 빠른 속도로 실행될수 있게 한다. 그러므로, Node는 비동기 입출력을 수행하는데 정말로 빠르다(네트워크, 서버의 하드디스크, 데이터베이스 입출력이나 파일 업로드하는 경우)



Node가 매우 빠르고, non-blocking 입출력을 제공한다는 것 외에도, Node는 싱글 쓰레드 / 이벤트 루프에 기반들 둔다. 그리고 그것은 Node.js의 장점이 되는 또다른 주요한 요소이다.


Node.js에서 Single thread / Event loop는 무엇을 의미하는가?

가장 잘 알려진 웹 서버인 아파치와 NGINX가 동시 접속을 어떻게 처리하는지 이해해보자.
아래에 두 웹서버를 비교하는 벤치마크가 있다.


*Note: 위의 벤치마크는 실제 상황의 예제가 아니다. 로컬호스트에서 스태틱 파일을 다룬 결과이다.

위의 벤치마크는 실제 상황과 같지는 않지만 두 서버의 성능 통계를 잘 보여준다. 아파치와 NGINX 초당 매우 많은 수의 요청을 처리할 수 있는 것처럼 보이지만, 동시 요청의 수가 증가함에 따라, NGINX에 비해 아파치의 성능이 크게 떨어지는 것을 볼수 있다.  그리고 NGINX는 여전히 동시 접속수가 증가할때에도 성능의 저하가 없이 거의 같은 속도를 유지한다.

같은 벤치마크에 대해서, 두 서버의 메모리 사용에 관한 관점에서 본 그래프를 살펴보자.

*Note: 위의 벤치마크는 실제 상황의 예제가 아니다. 로컬호스트에서 스태틱 파일을 다룬 결과이다.

위 그래프는 증가하는 동시 요청수에 대한 두 서버의 메모리 사용을 나타낸다. 두 서버 모두 많은 수의 동시 접속을 처리할 수 있지만 서버의 자원, 즉 메모리 사용에는 눈에 띄는 큰 차이가 있다. 그래프를 보면 아파치가 NGINX보다 같은 동시 요청 수에 대해 훨씬 더 많은 양의 메모리를 사용한다는 것은 분명하다. NGINX는 동시 요청을 매우 효율적인 이벤트 루프 - 싱글 쓰레드 방식으로 처리한다. 반면에 아파치는 복수 개의 쓰레드를 (각 접속 당 하나) 쏟아낸다. 이 쓰레드들이 많은 양의 메모리를 사용하고, 그 결과 서버에 많은 수의 동시 요청이 발생할 경우 아파치는 정말 비효율적이게 된다. NGINX는 접속 당 새로운 쓰레드를 실행하는 대신에 이벤트 루프를 사용함으로써 매우 안정적으로 유지된다.

Context swithcing은 쉽지가 않았다, 실제 상황에서 테스트 했을 때, 두 서버 모두 자원을 사용하고 증가 된 응답 시간을 보였다. 그러므로, 대규모 동시성에 대해서는, 새로운 쓰레드들을 운영체제에 쏟아낼 수가 없다. 이를 처리하기 위해서, 싱글 쓰레드 실행에 기반을 둔 Node는 서버에 만들어지는 모든 새로운 리퀘스트를 처리하기 위해 복수개의 쓰레드를 실행하는 대신에 이벤트 루프를 사용한다. 그리고 이것은 context switching에서 어떤 자원도 낭비하지 않음으로써 Node.js를 매우 강력하게 만든다. 따라서, Node.js는 대규모 동시성을 처리할 때나 가장 저 레벨 베이스를 제공할 때 매우 효율적이기 때문에 그 결과 프로그래머들은 Node 위에서 스트림을 할 수 있고 데이터를 버퍼에 저장할 필요가 없다. 단지 이것만이 아니라, Node.js는 프로그래머가 이벤트 기반 알고리즘으로 코드를 짤수 있게 해준다. Node.js는 또한 개발자들이 코드와 업무를 병렬로 실행하는데 힘을 실어주며 non-blocking 입출력을 제공한다. 아키텍쳐적 이점들을 가지는것 외에도, Node(매우 빠른 구글의 V8 자바스크립 엔진 기반으로 만들어진)는 Node.js를 빛처럼 빠르게 만든다.


Why Node.js over Others available?

Node.js를 사용하기 전에 다른 방법들을 알아보고 왜 이벤트 기반 접근법이 오늘날 프로그래머들 사이에서 잘 알려지지 않았는지 알아보자. 이것에 관한 세가지 기본적인 이유가 있다.

  • 문화적 선입견 : 첫 번째 이유는 non-blocking 입출력을 사용하는 것에 대한 문화적 선입견이다. 어느 언어를 배우든지 맨 처음으로 짜보는 프로그램은 다음과 같다.

    1
    2

    3
    4

    5
    6
    7
     
    //문자열 출력
    puts("Please Enter Your Green Name");

    //입력을 받기 위해 대기
    var green_name=gets();

    //문자열 출력
    puts("Your Green Name is: "+green_name);

    위의 코드는 입력 요구 알고리즘을 기반으로 한다. 코드를 짜는 이런 접근법은 코드를 막아(blocking)버린다. 위의 코드에서 사용자는 'green name'을 입력하도록 요구 받고 사용자가 입력할 때까지 기다린다. 코드가 멈춰버린다! 이 코드는 사용자가 'green name'을 입력할 때 까지 어떤 것도 할 수가 없다.

    만약 같은 코드를 다음과 같이 작성한다면..

    1
    2

    3
    4
    5
    6
    7
     
    8
    //문자열 출력
    puts("Please Enter Your Green Name");
     
    //콜백 함수 정의
    gets( function (green_name) {
       puts("Your Green Name is: "+green_name);
    });
     
    //기다리지 않고 다른 일을 처리한다.

    이것은 이벤트 기반의 프로그래밍 접근법이다. 이 프로그래밍 접근법을 사용함으로써 프로그래머들은 evented non-blocking I/O를 얻을 수 있다. 이런 유형의 프로그래밍 접근법이 막기 - 멈추기 - 코딩 접근법 처럼 잘 알려지지 않은 유일한 이유는 사람들이 이런 방식의 코딩 접근법이 어렵고 더 복잡하다고 생각하기 때문이다(실제로는 사실이 아니다). 그래서, 이벤트 주도 방식으로 어플리케이션을 코딩하는 것에 대한 선입견이 존재한다.

  • 부족한 인프라 Node의 방식으로 코딩을 하지 않는 또 다른 이유는 인프라의 부족이다. 만약 당신의 코드가 이벤트 중심으로 작동할 필요가 있다면, 절대 입출력을 막아서는 안되고, 당신의 코드가 싱글 쓰레드에 기반일 때 데이터베이스가 응답하는 것을 기다릴 수가 없고, 멈출 수도 없다. 대부분의 프로그래밍 라이브러리들은 이벤트 주도 프로그래밍 접근법을 지원할 수가 없다. 예를 들어: POSIX는 비동기 I/O를 지원하지 않는다. 지원하는 다른 것들은 같은 것을 얻기 위한 충분한 메뉴얼을 제공하지 않는다. C는 클로저와 익명 함수를 가지고 있지 않다. MySQL는 비동기 커넥션을 지원하지 않는다. 기타 등등. 이것들이 이벤트형 코드를 짜는데 어렵게 만든다.

  • 너무 많은 인프라 이벤트 주도 프로그래밍을 위한 플랫폼을 제공하는 라이브러리들이 있다. 루비의 Event Machine. 파이썬의 Twisted, Qt의 이벤트 루프가 그들이다. 비록, 이런 라이브러리들이 이벤트 프로그래밍을 위한 플랫폼에 non blocking I/O를 제공하고, 이 라이브러리들을 사용하면 효율적인 서버를 짜는 것이 상대적으로 간단할지라도, 사용자들은 이들을 어떻게 사용해야 할 지를 자주 헷갈려하는 경향이 있다. 예를 들어, 루비로 개발할 때 많은 라이브러리들을 가지고 있지만, 루비의 이벤트 머신 라이브러리는 MySQL 라이브러리와 조합될 수가 없다. 왜냐하면 모든 쿼리를 막아버리기 때문이다.

다행스럽게도,  Node를 사용한다면 이벤트 기반 어플리케이션을 개발이 더 이상 어려운 일이 아니다. Node는 매우 효율적이고, 순수한 이벤트 기반,non-blocking 웹 어플리케이션을 만들기 위한 인프라를 제공하고, 동시성 문제를 매우 효과적으로 처리할 수 있다. 이는 Node가 CommonJS 모듈시스템을 사용하고, non-blocking I/O를 제공하며, 구글에서 개발한 미친 스피드의 V8 자바스크립트 엔진에서 돌아가기 때문이다.  Node.js는 이벤트 기반 프로그래밍을 정말 쉽고, 매우 효율적이고, 빛과 같이 빠르게 만든다.
 
Node.js를 시작하려 한다면, Node.js 설치하기를 읽어봐라.

번역: @PillarLee 이병주
http://yambbam.kr/docs/why-node.js-single-thread-event-loop-javascript.html