thumbnail
1_2. 노드의 특징 - 복습
node_study2
2022.12.25.

1_2. 노드의 특징 - 복습

1_2_1. 이벤트 기반

  • 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식
    • 이벤트의 예: 클릭, 네트워크 요청(주소창에 주소입력하는 행위), 타이머 등
    • 이벤트 리스너: 이벤트를 등록하는 함수
    • 콜백 함수: 이벤트가 발생했을 때 실행될 함수

대부분의 언어는 이벤트 기반이다.
프로그램에선 메모리에 미리미리 이런 이벤트 핸들러를 등록해 놓을 수 있다.

주소창에 주소를 입력하는 행위도 이벤트이다.
주소창에 주소를 입력하면

  1. dns 서버에서 ip를 받아오고,
  2. 해당 ip 주소로가서 방화벽을 뚫고,
  3. 그 서버에서 응답 받아서 다시 dns 거쳐서 주소 입력을 한 컴퓨터로 돌려보내준다.

위와 같은 작업을 0.1ms 내에 하고 있다.

1_2_2. 논블로킹 I/O

  • 논블로킹: 오래 걸리는 함수를 백그라운드로 보내서 다음 코드가 먼저 실행되게 하고, 나중에 오래 걸리는 함수를 실행
    • 논블로킹 방식 하에서 일부 코드는 백그라운드에서 병렬로 실행된다.
    • 일부 코드: I/O 작업(파일 시스템 접근, 네트워크 요청), 압축, 암호화 등
    • 나머지 코드는 블로킹 방식으로 실행된다.
    • I/O 작업이 많을 때 노드 활용이 극대화된다.

논블로킹은 ‘동시’가 아니다.
비슷한 말로 ‘동기’, ‘비동기’가 있다.
간단하게 말하면

  1. 노드는 블로킹이면서 동기
  2. 비동기면서 논블로킹

위와 같이 2가지만 있다고 생각하면 된다.
동기 / 비동기 / 블로킹 / 논블로킹은 모두 서로 다른 뜻이다.
하지만 노드에서는

  1. 동기이면서 논블로킹인 경우
  2. 비동기이면서 블로킹인 경우

거의 위 2가지 경우밖엔 없다.

1_2_3. 흔히하는 오해 - 비동기이면서 논블로킹

비동기이면서 논블로킹인 경우, ‘노드가 동시에 돌아간다’, ‘프로그램이 동시에 돌아간다’는 오해를 한다.
노드에서 동시를 구현하기에는 매우 어렵다.
사실상 일부를 빼곤 거의 없으니까 그 일부만 외우면 된다.

  • 동기: 코드가 순서대로 실행된다.
  • 비동기: 코드가 순서대로 실행되지 않는다.
  • 블로킹: 코드가 순서대로 실행된다.
  • 논블로킹: 코드가 순서대로 실행되지 않을 수도 있다.

논블로킹이라고 해서 코드가 랜덤하게 실행되는 것은 아니고 어떤 규칙이 있다.
이 규칙이 실행 컨텍스트를 배울 때 나온다.
실행 컨텍스트와 이벤트 루프, 이 두개를 배우면 논블로킹일 때 어떻게 돌아가는지 예측이 된다.

1_2_4. 프로세스 VS. 스레드

  • 프로세스와 스레드

    • 프로세스: 운영체제에서 할당하는 작업의 단위를 말한다. 프로세스간 자원공유는 없다.
    • 스레드: 프로세스 내에서 실행되는 작업의 단위를 말한다. 부모 프로세스 자원을 공유한다.
  • 노드 프로세스는 멀티 스레드이지만 직접 다룰 수 있는 스레드는 하나이기 때문에 싱글 스레드라고 표현한다.

  • 노드는 주로 멀티 스레드 대신 멀티 프로세스를 활용한다.

  • 노드 14버전부터 멀티 스레드 사용 가능하다.

노드는 멀티 스레드인데, 개발자가 컨트롤할 수 있는 스레드는 하나라 싱글 스레드라고 했던 것이다.
그럼 노드를 실행했을 때, 그 한개를 제외한 나머지 스레드는 뭘 하고 있을까?
나머지 스레드는 코드를 동시에 돌릴 준비를 하고 있는다.
즉, 대기를 하고 있다고 생각하면 된다.
어떤 특정한 조건이 만족되면 이 대기를 하고 있는 스레드들이 해당 코드들을 실행시켜준다.

노드가 아예 싱글 스레드였다면 동시라는 개념이 나올 수 없다.
하나의 일을 하면서 다른 일을 할 수가 없다.
분명 스레드가 다른 것이 있으니까 동시에 할 수 있는 것이다.

1_2_5. 싱글 스레드

  • 싱글 스레드라 주어진 일을 하나밖에 처리하지 못한다.
    • 블로킹이 발생하는 경우 나머지 작업은 모두 대기해야 한다. 비효율이 발생한다.
  • 주방에 비유(점원: 스레드, 주문: 요청, 서빙: 응답)
  • 대신 논 블로킹 모델을 채택하여 일부 코드(I/O)를 백그라운드(다른 프로세스)에서 실행이 가능하다.
    • 요청을 먼저 받고, 완료될 때 응답한다.
    • I/O 관련 코드가 아닌 경우 싱글 스레드, 블로킹 모델과 같아진다.

보통 스레드는 하나의 CPU의 코어 1개를 사용한다.
요즘 8코어, 16코어, 32코어 이렇게 말을 하는데, 만약 내가 엄청 비싸게 32코어짜리 컴퓨터를 샀다.
그런데 노드를 실행하면 그 중에서 딱 1개의 코어만 쓰고 나머지 31개 코어는 놀고있는 것이다.
심지어 그 1개의 코어에 일이 너무 많아서 그 코어가 터지기 직전이라면?
32개 중에 그 1개를 만져봤는데 그 1개만 불탈듯이 뜨겁고 나머지 31개는 얼음처럼 차갑고 이런 상황이다.

즉, 싱글 스레드가 효율적인 구조냐 했을 때 효율적인 구조는 아닌 것이다.

1_2_6. 멀티 스레드 모델과의 비교

  • 싱글 스레드 모델은 에러를 처리하지 못하는 경우 멈춘다.
    • 프로그래밍 난이도가 쉽고, CPU, 메모리 자원을 적게 사용한다.
  • 멀티 스레드 모델은 에러 발생시 새로운 스레드를 생성하여 극복한다.
    • 단, 새로운 스레드 생성이나 놀고 있는 스레드 처리에 비용이 발생한다.
    • 프로그래밍 난이도가 어렵다.
    • 스레드 수만큼 자원을 많이 사용한다.

1_2_6_1. 멀티 스레드를 하면 비동기 처리가 필요없나요?

멀티 스레드를 하면 비동기 처리가 필요 없냐고 하셨는데, 멀티 스레드를 해도 비동기 처리는 해야된다.
멀티 스레드를 안하려고 노드를 하는 것이다.
멀티 스레드 프로그래밍이 어렵기 때문에 노드를 하는 것인데, 프로그래밍은 효율적으로 돌리고 싶은 것이다.
그런데 그래도 사람들이 멀티 스레드를 하고 싶은 경우가 있을 텐데, 아예 못하게 하는 것보단, 할 수 있게 열어주는 것이 낫지 않을까해서 멀티 스레드를 추가만 해준 것이지, 노드JS에서 멀티 스레드가 주력이 될 일은 없다.

1_2_7. 멀티 스레드 활용

  • 노드 14버전

    • 멀티 스레드를 사용할 수 있도록 worker_threads 모듈을 도입했다.
    • CPU를 많이 사용하는 작업인 경우에 이를 활용할 수 있다.
    • 멀티 프로세싱만 가능했던 아쉬움을 달래준다.
  • 멀티 스레딩과 멀티 프로세싱 비교

멀티 스레딩 멀티 프로세싱
하나의 프로세스 안에서 여러 개의 스레드 활용 여러 개의 프로세스 사용
CPU 작업이 많을 때 사용 I/O 요청이 많을 때 사용
프로그래밍이 어려움 프로그래밍이 비교적 쉬움
Thank You for Visiting My Blog, Have a Good Day 😆
© 2022 Developer hyungju-lee, Powered By Gatsby.