Reactive Stream

fireFox·2022년 5월 2일
0

Reactive Programming

목록 보기
2/3
post-thumbnail

개요

Non-blocking, Back pressure를 이용한 비동기 데이터 처리의 표준

간단히 말해 리액티브 프로그래밍을 위해 정의해놓은 인터페이스 모음이다. 개발자는 Reactive Stream에 정의된 인터페이스를 구현함으로써 리액티브한 프로그램을 개발할 수 있다.
Reactive Stream GitHub에 들어가서 살펴보면 인터페이스 선언이 전부인것을 확인할 수 있다.

하지만 Reactive Stream API는 복잡한 구현규칙이 있고 이를 전부 만족하게 구현하는건 상당히 어려운일이다. RxJava, Spring WebFlux등 검증된 구현체 라이브러리들이 많이 있기때문에 이를 이용해서 구현하는게 여러모로 유리하다.

Reactive Stream 은 다음 3가지 특성이 있다.

  • Streaming
  • 비동기 & Non-blocking 방식
  • Back pressure

Streaming

Streaming과 전통적인 데이터 처리 방식의 비교

  • 전통적인 데이터 처리 방식

전통적인 데이터 처리 방식은 DB에 요청해서 모든 데이터를 어플리케이션 메모리로 가져온 후에야 다음 처리를 할 수 있다. 이 방식의 문제점은 어플리케이션 메모리 적재 과정이 끝나야만 응답메시지를 만들 수 있으며, 데이터 크기가 메모리보다 크면 ‘out of memory’ 에러가 발생한다는 점이다.
또한 순간적으로 많은 요청이 몰리면 Garbage Collection이 폭증하여 서버가 정상적으로 응답하지 못하는 경우가 생길 수 있다.

  • 스트리밍 처리 방식

스트리밍 처리 방식은 어플리케이션 메모리에 한번에 가져온 데이터를 다 올리지 않기때문에 크기가 작은 시스템 메모리로도 많은 양의 데이터를 처리할 수 있다.
스트리밍 방식은 입력 데이터에 대한 파이프 라인을 만들어 데이터가 들어오는 대로 물 흐르듯이 구독(subscribe)하고, 처리한 뒤, 발행(publish)까지 한 번에 연결하여 처리한다.

비동기 & Non-blocking 방식

만약 특정 웹 페이지를 로딩하기 위해 API A,B,C가 필요하고 응답시간이 아래와같이 소요된다면
A - 1초
B - 2초
C - 3초

Sync & Blocking : 6초 (1초+2초+3초)
Async & Non-Blocking : 3초 (가장 소요시간이 긴 API의 소요시간)

동기 & 블록킹 방식은 쓰레드가 다른 함수의 작업이 끝날때까지 대기해야 하기 때문에 6초가 소요된다. 하지만 비동기 &논블록킹 방식은 함수를 동시에 호출하고 먼저 끝나는 함수부터 처리하기 때문에 가장 긴 API의 소요시간인 3초가 소요된다.

Sync & Blocking방식과 비교하여 Async & Non-Blocking방식을 사용하는 장점이 2가지 있다.

  • 속도가 빠르다 : 요청을 동시에 처리 할 수 있기 때문에 더 빠른 속도를 보여준다.
  • 효율적인 리소스 사용 : 현재 쓰레드가 블록킹되지않고 다른 업무를 처리할 수 있기 때문에 적은수의 쓰레드로 더 많은 요청을 처리 할 수 있다.

Back pressure

Back pressure는 배압이라는 뜻인데 위 사진처럼 밸브의 압력으로 유입수량을 조절해주는 기능을 한다.
Reactive Stream에서의 Back pressure도 비슷한 의미이다. Publisher가 발행하는 이벤트가 지나치게 많아 Subscriber가 재 시간에 다 소비하지 못한다면 이를 조절할 수 있다.

만약 생산자가 10개의 데이터를 1초마다 발행하고, 소비자는 소비를 1개 데이터를 소비하는데 1초가 소요된다면 소비를 제때 못하기 때문에 데이터는 스트림에 계속 쌓이게 된다.
계속 쌓이게 되면 메모리가 넘치게되고 결국 OutOfMemory로 시스템이 터질것이다.

이를 해결하려면 소비자가 소비할 수 있는 정도까지만 생산자에게 데이터를 요청하도록 통제해줄 필요가 있다. 이러한 처리를 가능하게 하는게 바로 BackPressure 방식이다.

Reactive Stream의 기본 인터페이스들

Reactive Stream은 다음 4가지 기본 인터페이스를 제공한다.

  • Publisher : 데이터를 생성하고 데이터 생성을 통지한다.
  • Subscriber : 데이터를 구독하고 통지 받은 데이터를 처리한다.
  • Subscription : Publisher, Subscriber 간에 데이터가 교환될 수 있도록 연결하는 역할을 하며, 전달 받을 데이터의 개수를 요청하고 구독을 해지한다.
  • Processor : Publisher, Subscriber를 모두 상속받은 인터페이스이다. 어떤 이벤트를 subscription할것인가 결정한다.

동작흐름

1) Subscriber는 데이터를 생성하는 Publisher에게 구독을 요청(subscribe)
2) Publisher는 onSubscribe를 사용해 Subscriber에게 데이터 전달.
3) Publisher와 Subscriber는 직접 통신을 하지않는다. Subscription가 중간에서 데이터를 중재한다. Subscriber는 Subscription에 요청하고 Subscription이 Publisher에 데이터를 요청한다.
4) Publisher는 데이터를 Subscription에 전달하고 Subscription이 Subscriber에게 데이터를 전달한다.
5) 작업완료 or 에러 전달.

참고자료

https://engineering.linecorp.com/ko/blog/reactive-streams-with-armeria-1/

profile
기억날때 기록하자

0개의 댓글