"카카오와 우아한형제들이 선보이는 Java 가상 스레드 혁신"

Moon·2024년 4월 23일
0

제목을 고민하다가 ChatGPT에게 추천해달라했는데, 너무 슴슴합니다.. 자극적인 것에 익숙해져버린 걸지도..🤦‍♀️🤦‍♂️


오늘 까맣게 잊고 있었던 우아한테크세미나가 열리는 날이었고, 동기가 리마인드 해준 덕분에(고마운 철!) 퇴근 후 유튜브로 볼 수 있었습니다.

강연자 분이 직접 언급하셨지만, 이미 우아한 기술 블로그에도 올라와 있는 내용입니다.

해당 기술 블로그에 모자이크를 해서 누군지 모르겠지만👩 (내 월급 도둑 영한..킴...)

그 당시엔 Virtual Thread가 JDK 정식 feature가 아니었기 때문에 코틀린의 coroutine이 유일한 선택지였다고합니다. 결국 코틀린을 막지 못 하신 영한킴..(제 월급은 왜 안 막아 주셨나요!)

이후 Project Loom(Virtual Thread)이 feature로 등록됨에 따라 딥다이브를 진행했고 그에 따른 결과를 발표해주셨습니다.

따끈따끈한 우아한 다시보기는 👉👉[4월 우아한테크세미나] ‘Java의 미래, Virtual Thread’


작년 12월 Java 21에 Virtual Thread가 추가되었다는 걸 얼핏 들었습니다.

예전에 온라인으로 참여했던(항상 오프라인 추첨은 떨어져서..) Kakao Tech Meet에서 해당 주제를 발표하시는 걸 보았는데 그런게 있구나~ 하고 필요한 부분만 쓱 듣고 넘겼었습니다. 그래도 다행인건 항상 유튜브에 발표를 남겨주셔서 오늘 또 한 번 보게 되었습니다.

두 발표가 비슷하면서도 주목한 부분이 달랐습니다. 참고로 직접 해보길 희망하시는 개발자 분이라면, 카카오 영상에서 실제로 virtual thread를 사용하는 방법까지 가이드를 해주셔서 참고하면 좋을 것 같습니다.


온정이 남아있는 카카오 다시보기는 👉👉 [제4회 Kakao Tech Meet] JDK 21의 신기능 Virtual Thread 알아보기 (안정수 James)


이번 게시글은 다음 순서로 작성할 예정입니다.

1. 자바의 (기존) thread

2. 자바의 virtual thread가 등장한 계기(기존 스레드와 비교를 통해)

최대한 두 영상의 내용을 간추려 요약해보려고 합니다.


1. 자바의 (기존) Thread

비교를 위해 자바의 (기존) 스레드 라고 명명했습니다.

사실 virtual thread가 등장하기 이전까지 그냥 스레드는 스레드였는데, 기존의 스레드는 어떻게 작동하고 있었을까요?

  1. 자바의 기존 스레드는 비용이 크다 혹은 비싸다

참고) 두 강연자 모두 비용이 크다 혹은 비싸다 라는 표현을 사용하십니다. '시스템콜', '커널', '컨텍스트 스위칭' 등과 같은 OS(운영체제)와 관련된 이해가 필요합니다. 쉽게 설명하면, 어떤 처리를 위해 들어가는 간접적인 처리 시간 혹은 메모리(오버헤드)가 발생한다고 생각하면 좋을 것 같습니다.

  • 스레드가 비싼 이유는 무엇일까요? 이는 자바의 스레드가 OS 스레드를 Wrapping한 것이기 때문입니다. (Platform Thread)
  • 자바 애플리케이션에서 스레드를 사용하는 것은 실제로는 OS 스레드를 사용하는 것입니다. (OS에 의해 스케줄링 되기 때문에 시스템콜이 발생합니다)
  • OS 스레드는 생성 갯수가 제한적이고, 생성, 유지하는 비용이 비쌉니다. (메모리가 최대 2mb까지 사용)

  1. OS의 스레드와 자바의 스레드는 1:1 맵핑이다.

기존 Java의 스레드 모델은 Native Thread로, Java의 유저 스레드를 만들면 Java Native Interface(JNI)를 통해 커널 영역을 호출하여 OS가 커널 스레드를 생성하고 맵핑하여 작업을 수행하는 형태입니다.
그림을 보고, 쉽게 이해할 수 있었습니다.


2. 자바의 virtual thread가 등장한 계기(기존 스레드와 비교를 통해)

그렇다면, 자바의 Virtual Thread는 왜 등장하게 되었을까요? 아무래도 앞서 말한, 비싼 비용을 해결하기 위해 등장해야 할 것 같습니다.

이를 이해하기 위해 우선, Thread Per Request 방식에 대한 이해가 필요합니다.

기본적인 Web Request 처리 방식으로 Thread Per Request 방식(하나의 요청 - 하나의 스레드)을 사용하게 되는데 처리량을 높이기 위해 더 많은 스레드가 필요합니다.

하지만! 스레드는 무한정으로 늘릴 수 없다는 한계가 있습니다.

반면, Virtual Thread는 우아한 강연자님의 표현을 빌리자면 거의 무한정 생산할 수 있습니다.

먼저, Virtual Thread와 기존 Thread의 메모리 사이즈, 생성시간, 컨텍스트 스위칭 시간을 비교해봅시다.

스레드는 2mb까지 커질 수 있는 반면, 가상 스레드는 50kb밖에 되지 않습니다.

또한 스레드 생성시간에서도 기존 스레드는 1밀리세컨드에 가능한 반면, 가상 스레드는 10마이크로 세컨드 내에 가능합니다.


가상 스레드는 기존 스레드의 1:1 맵핑 방식이 아닌 캐리어 스레드와 1:N 맵핑으로 구성되게 되며, JVM에 의해 스케줄링 됩니다.

그렇다면 이게 전부냐..? 라고 할 수 있지만, 가상 스레드의 또 다른 장점은 Non-blocking방식을 지원한다는 것입니다.

스레드에서 I/O 작업이 발생하게 되면 Blocking이 발생하고 이로 인해 작업 처리가 늦어진다는 단점이 있습니다.

참고) 기존에는 Spring WebFlux를 활용하여 Blocking Time을 줄이고 있습니다

하나 간단한 퀴즈를 내주셨습니다.

Tomcat (기존)스레드 10개
10초가 소요되는 API 호출
100회 동시 호출 시 걸리는 시간은?

정답은 100회 / 10(스레드) * 10(소요시간) = 100초

그렇다면 실제 (기존) 스레드와 가상 스레드를 사용하였을 때 차이는 어떠하였을까요?

일반 스레드는 130초가 소요된 반면,

가상 스레드는 10초만에 완료되었습니다.


요약을 한 내용 외에도, 스케줄러 ForkJoinPool 등 다양한 이야기를 해주셨으나 담기에 많은 내용이라 여기까지 적었습니다.

또한 두 분 모두 강조한 점은 '반드시 가상 스레드가 좋은 것은 아니다' 였기 때문에 꼭, 적용하기 전 유의해주신 부분들에 대해 재고할 필요가 있는 것 같습니다.

다음에는 실제 가상 스레드를 생성하고 테스트하는 것까지 작성해보겠습니다!

profile
안녕하세요. Moon입니다!

1개의 댓글

comment-user-thumbnail
2024년 5월 22일

멋지네요!!

답글 달기