Sync/Asnyc & Blocking/Non-Blocking

hyeonjeong33·2022년 11월 6일
1
post-thumbnail

들어가며
Node.js가 사용하는 비동기(asynchronous) 논블로킹(non-blocking) 방식을 이해하기 위해 정리하는 글이다.

Synchronous / Asynchronous

관심사 -> 호출되는 함수의 작업 완료 여부를 누가 신경쓰는가?

  • 호출하는 함수가 호출되는 함수의 작업 완료 후 리턴을 기다리거나, 또는 호출되는 함수로부터 바로 리턴 받더라도 작업 완료 여부를 호출하는 함수 스스로 계속 확인하며 신경쓰면 Synchronous

  • 호출되는 함수에게 callback을 전달해서, 호출되는 함수의 작업이 완료되면 호출되는 함수가 전달받은 callback을 실행하고, 호출하는 함수는 작업 완료 여부를 신경쓰지 않으면 Asynchronous

동기(Synchronous)란?

특정 작업을 요청하면, 그 즉시 작업의 완료 여부와 처리 결과를 확인할 수 있는 형태를 말한다. 요청한 작업의 완료 여부와 결과를 바로 알 수 있다는 장점이 있다. 그러나, 요청한 작업의 완료 여부와 작업 결과를 반환받는 데 필요한 시간이 긴 경우 문제가 발생할 수 있다.

  • 이 경우 후행 작업의 수행 가능 시점도 그에 비례하여 늦어지게 되므로, 짧은 시간에 다량의 작업을 요청해야 할 경우에 주의가 필요하다.

일반적으로 싱글스레드(Single-thread)를 사용한 처리 방식이 이에 해당한다.

비동기(Asynchronous)란?

특정 작업을 요청한 즉시 바로 그 작업의 완료 여부와 작업 결과를 바로 확인할 수 없는 방식이다. 요청한 작업의 완료 여부와 반환값은 콜백(Callback)을 통해 전달받을 수 있다. 이 콜백이 실행되는 시점은 각 작업별로 천차만별이다.

이 방식은 이미 요청한 작업의 결과를 기다리고 있을 필요 없이 바로 다음 작업을 요청할 수 있어 작업 처리 효율이 높아진다는 장점이 있다.

다만 특정 작업의 경우, 선행 작업의 결과값을 이어받아 순차적으로 작업을 진행해야 할 수 있다. 이런 작업을 비동기 작업으로 구현할 경우 프로그램이 복잡해질 수 있으므로 주의를 요한다.

일반적으로 멀티스레드(Multi-thread)를 사용한 처리 방식이 이에 해당한다.

Blocking / Non-Blocking

관심사 -> 호출되는 함수가 즉시 반환되는가?

  • 호출된 함수가 자신이 할 일을 모두 마칠 때까지 제어권을 계속 가지고서 호출한 함수에게 바로 돌려주지 않으면 Block
  • 호출된 함수가 자신이 할 일을 채 마치지 않았더라도 바로 제어권을 건내주어(return) 호출한 함수가 다른 일을 진행할 수 있도록 해주면 Non-Block

블로킹(Blocking)이란?

특정 작업이 실행 요청을 받아 실제로 수행되는 동안, 다른 작업은 작업을 진행하지 못하고 대기해야만 하는 방식을 말한다. 작업이 순차적으로 이루어지기에 작업 흐름을 쉽게 이해할 수 있다는 장점이 있지만, 블로킹이 이루어지는 동안은 하드웨어 리소스를 효율적으로 이용하지 못한다는 단점이 있다. 특히 블로킹이 일어나는 작업이 오래 걸릴 경우 이 단점은 더욱 두드러진다.

논 블로킹(Non-Blocking)이란?

특정 작업이 이미 수행 중이더라도, 그것과 상관 없이 바로 다른 작업을 수행 시키는 것이 가능한 방식을 말한다. 리소스가 낭비되는 시간이 없기에, 하드웨어 리소스를 균일하고 효율적으로 이용할 수 있으나, 업무 흐름이 복잡해지는 단점이 있다.

실생활에서의 예

은행과 커피숍이라는 친숙한 두 가지 모델로 예를 들어 비교해보자.

  1. 은행(blocking)

    은행 지점에 들어서면 눈 앞에 고객들이 줄을 서 있다. 대기열 앞에는 여러 창구가 있고 열려 있는 각 창구에는 단일 고객을 지원하는 창구 직원이 있다.

    이때, 은행 거래의 처리 모델은 "blocking"이다.

    • 단일 창구는 한 번에 한 명의 고객만 도울 수 있다.
    • 은행원은 거래의 모든 단계를 순서대로 처리한다.
    • 은행원이 거래의 한 단계를 처리할 수 없는 경우(예를 들어, 감독자의 승인이 필요하다고 가정), 은행원은 승인을 기다리는 동안 업무를 진행할 수 없다.
    • 전체 거래가 완료되면 창구에서 나온다.

    이 상태에서 더 많은 고객에게 서비스를 제공하거나 더 빠르게 고객에게 서비스를 제공하기 위해서는 다음의 두 가지 방식으로 확장할 수 있다.

    • 수직: 더 많은 은행원 추가
    • 수평: 더 많은 은행 지점 추가

    이러한 은행 거래의 성격은 동기(synchronous)이다. 창구 직원이 다른 고객을 지원하려면 진행하고 있던 모든 업무를 완료해야 한다.

  2. 커피숍(non-blocking)
    동네 커피숍에 들어가니 눈 앞에 손님들이 줄을 서 있다. 대기열 앞에는 주문을 받고 결제를 처리하는 카운터 직원이 한 명 있고, 카운터 뒤에 한 명 이상의 바리스타가 주문을 준비하고 있다.

    이때, 커피숍 거래의 처리 모델은 "non-blocking"이다.

    • 한 명의 카운터 직원은 한 번에 한 명의 고객만 도울 수 있다.
    • 바리스타가 한 번에 하나의 주문을 준비한다.
    • 카운터 직원과 바리스타가 주문을 완료하는 모든 단계를 공유한다.
    • 바리스타가 주문을 준비하는 동안 카운터 직원은 다른 고객의 주문을 받을 수 있다.
    • 나중에 주문이 준비되면 이름이 불리고 앞으로 나가서 수령한다.

    이 상태에서 더 많은 고객에게 서비스를 제공하거나 더 빠르게 고객에게 서비스를 제공하기 위해서는 다음의 두 가지 방식으로 확장할 수 있다.

    • 수직: 더 많은 바리스타 추가
    • 수평: 더 많은 커피숍 추가

    이러한 커피숍 트랜잭션의 특성은 비동기식(asynchronous)이다. 카운터 직원은 단순히 주문을 받은 후 결제를 처리하고 충분한 정보를 수집하여 주문이 준비되면 고객에게 알릴 수 있다. 그런 다음 카운터 직원은 다음 고객을 돕고 바리스타는 동시에 주문을 처리한다.

  3. 정리
    (일부 은행/커피숍에서는 여러 명의 직원이 있을 수 있기 때문에 위의 비유가 완벽한 것은 아니지만) 정리하면 아래와 같다.

    • Node.js
      : 커피숍 모델을 사용한다. 단일 실행 스레드는 모든 JavaScript 코드를 실행하고 결과를 기다리는 콜백을 제공한다.

    • 다른 소프트웨어 스택들
      : 은행 모델을 사용한다. 확장을 위해 더 많은 스레드(또는 프로세스)가 생성된다. Apache웹 서버는 은행 확장성 모델을 사용하는 한 가지 예이다.

    물론 두 모델 모두 더 많은 서버를 추가하여 수평 확장성을 달성할 수 있다.

  4. 비동기 프로그래밍의 어두운 면

    만약 카운터 직원이 주문과 결제를 받는 것보다 고객들과 수다를 나누는 데 더 관심이 많다면 어떻게 될까?

    • 대기줄이 밀리고 바리스타가 일을 하지 않는 상태가 되며 전체 업무 프로세스가 중단될 것이다.

    이와 같이 하나의 응용 프로그램이 제대로 작동하지 않아 프로세스가 중단되거나 느려지는 문제는 노드에서도 발생할 수 있다.

Synchronous / Asynchronous & Blocking / Non-Blocking

진정한 차이점은 각 키워드가 바라보는 관심사의 차이라고 볼 수 있다. 작업 특성 그 자체에 차이점이 있는 것이 아니다.

  • 동기/비동기: 각 작업이 주고받는 데이터의 상태와 흐름을 어떻게 제어할 것인가. 데이터의 일관성을 유지한다.
  • 블로킹/논블로킹: 각 작업의 수행 형태와 우선순위에 따라 각 작업의 수행가능 시기를 어떻게 제어할 것인가. 주 관심사는 특정 작업의 행위가 일어나는 시점을 관리하는 것이다.

데이터의 흐름 제어와 작업 수행 시기를 제어하는 것은 별개이기 때문에, 논블로킹 작업을 하던 도중에도 공유 데이터의 일관성 유지를 위해 동기식 작업이 간혹 발생할 수 있으며, 비동기 작업을 하는 도중에도 간혹 블로킹이 일어날 수 있는 것이다.

참고
https://developer.ibm.com/tutorials/learn-nodejs-node-basic-concepts/?mhsrc=ibmsearch_a&mhq=non-blocking
https://studyandwrite.tistory.com/486
https://alnet.tistory.com/9
https://iceflower.gitbooks.io/vertx-studybook/content/thread-safe.html

profile
👩🏻‍🌾기억을 기록하고 공유하자📚

0개의 댓글