본문 바로가기

Back-End/Spring

스프링 blocking vs non-blocking : R2DBC vs JDBC & WebFlux vs Web MVC

들어가기 전

해당 글은 https://technology.amis.nl/2020/04/10/spring-blocking-vs-non-blocking-r2dbc-vs-jdbc-and-webflux-vs-web-mvc/ 를 번역한 글입니다. 영어가 더 편하시다면 이 글을....

 

 

스프링 프레임워크 버전 5는 리액티프 프로그래밍을 위한 WebFlux를 2017년 8월에 릴리즈 하였고, 2019년 12월에 리액티프 드라이브를 사용한 관계형 데이터베이스인 R2DBC를 릴리즈하였다. 해당 포스팅에서는 WebFlux와 R2DBC를 사용했을 때 더 높은 동시성에 대해 알아본다.  이 둘을 사용하면 더 빠른 응답과 더 높은 처리량을 가지고, 뿐만 아니라 메모리도 조금 사용하고 요청당 CPU도 조금 사용한다. 그리고 JAR 용량까지 줄어든다고 한다.

개발을 하다보면 항상 정답보다는 장단점과 상황에 따른 선택이 따른다. 해당 원글대로라면 WebFlux와 R2DBC를 쓰면 무조건 좋다인데, 어떠한 단점이 있을까?

비교군들

  • Spring Web MVC + JDBC
  • Spring Web MVC + R2DBC
  • Spring WebFlux + JDBC
  • Spring WebFlux + R2DBC

4가지 구현체들을 비교하기 위해 동시 요청을 4->500으로 늘려보고,  4코어로 서비스에 할당을 하였다. connection pool은 100으로 설정하였다. 

 

데이터베이스에서 10개의 record를 읽고 JSON으로 리턴해주는 GET 서비스가 있다고 가정하자. 먼저, 서비스에 부하를 주어 2초 동안 primed(서비스가 휘청거리는 상태) 로 만들었다. 

 

성능 측정 결과

측정한 지표는 아래와 같다

  • 응답시간 ( response time )
  • 처리량 ( throughput - number of requests )
  • CPU 사용량 : user and kernal time ( based on /proc/PID/stat )
  • 메모리 사용량 : private and shared process memory ( based on /proc/PID/maps)

Response time

역시나 WebFlux라고 무조건 높은 concurrency를 보장하는건 아니다. R2DBC 덕분에 높은 concurrency 시에 빠른 응답 시간을 가진다.

 

Throughput

위의 그래프를 보면 낮은 concurrency 에서는 Spring MVC + JDBC가 제일 최선의 선택이다. 그리고 JDBC를 쓰고 있다면 Spring Web MVC에서 Spring Webflux로 넘어가는게 좋은 선택은 아니다.

 

CPU

process user와 kernel time의 합을 구한 값이다. 의외로 WebFlux + JDBC 가 제일 CPU를 조금 사용하였다? 하지만, 아까 throughput 그래프를 보면 이 조합은 적은 요청을 처리했기 때문임을 알 수 있다. 그렇다면 아래와 같이 request 당 cpu 사용량을 보자.

 

역시나 낮은 concurrency 환경에서는 Web MVC + JDBC 가 가장 효율적임을 알 수 있다. 그리고 역시나 WebFlux에다가 JDBC를 같이 쓰는건 최악의 선택임을 알 수 있다. 즉, non-blocking 을 선택할 때 blocking component가 있는지 꼭 체크해야 된다.

 

Memory

메모리는 실행이 끝난 시점에 process private memory를 기준으로 측정하였다. 메모리 사용량은 garbage collection에 의존적이다. G1GC는 JDK 11.0.6 버전을 사용하였고, Xms=0.5Gb, Xmx =8GB로 설정하였다.

역시나 동시성이 적을 때는 Spring Web MVC + RDBC가 좋은 선택이였고, Spring Webflux + R2DBC는 동시성이 높아져도 안정적인 메모리 사용량을 보여주었다.

 

요약

R2DBC + Webflux가 높은 동시성때는 좋은 선택이다.

  • 요청당 CPU를 조금 사용함
  • 용청당 메모리가 조금 필요함
  • 응답시간이 빠름
  • 처리량도 높아짐
  • JAR도 가벼워짐
  • 대략 200 concurrenct request 밑으로는 Spring Web MVC + JDBC가 좋은 선택이다.

R2DBC를 선택했을 때 직면해야할 과제들...

  1. JPA는 아직 Spring Data R2DBC와 같은 reactive repositories를 다루지 않는다. 즉, R2DBC를 사용하려면 첨부터....
  2. 모든 관계형 데이터베이스가 reactive driver를 지원하는 것은 아니다
  3. 자바 개발자가 자바 15쯤에 driver landscape가 바뀔거고 결국은 R2DBC가 JDBC의 대체제가 되지 않을 것이라고 했다.