Quarkus 놀랍도록 빠른 부팅 시간과 엄청나게 낮은 메모리
Quarkus는 Java를 Docker 컨테이너와 Kubernetes 환경에 최적화시키는 것을 목적으로 한 것입니다. 컨테이너의 확산으로 기존의 소프트웨어도 변하기 시작했습니다.
기존 에는 상상할 수 없는 놀랍도록 빠른 부팅 시간과 엄청나게 낮은 메모리를 사용합니다. Kubernetes 와 같은 컨테이너 오케스트레이션 플랫폼에서 즉각적인 스케일업과 고밀도로 메모리를 사용할 수 있게 합니다.
위의 그림은 REST 와 REST CRUD 애플리케이션에 대해 기존 스택간의 메모리 사용량과 시작시간을 포함한 최초 응답시간을 비교한 챠트입니다.
Quarkus started in 0.008s
기존 애플리케이션 스택의 성능 비교
REST 애플리케이션에 대한 메모리 점유율 비교
REST 애플리케이션 환경에서 기존 애플리케이션 대비하여 메모리를 10 배 이하로 사용하는 것을 확인할 수 있습니다.
REST + CRUD 에 대한 메모리 점유율 비교
REST + CRUD 애플리케이션 일 경우에 기존 애플리케이션 대비 메모리를 6 배 이하로 점유하는 것을 확인할 수 있습니다.
REST 에 대한 최초 응답시간
REST 애플리케이션 일 경우 기존 애플리케이션 대비 시작 시간과 최초 응답 시간이 30 배 빠른 것을 확인할 수 있습니다.
REST + CRUD 최초 응답시간
REST + CRUD 애플리케이션 일 경우 기존 애플리케이션 대비 시작 시간과 최초 응답 시간이 17 배 빠른 것을 확인 할 수 있습니다.
가볍고 빠른 이유는 무엇 문일까요 ?
처음부터 Quarkus는 컨테이너의 첫 번째 철학을 중심으로 설계되었습니다. 이는 Quarkus가 다음과 같은 방법으로 메모리 사용량과 빠른 시작 시간에 최적화되어 있다는 것을 의미합니다.
- Graal / SubstrateVM에 대한 퍼스트 클래스 지원
- 섭스트레이트 (Substrate) 는 처음부터 설계에서 중요한 부분이었습니다. 애플리케이션이 기본 이미지로 컴파일되면 훨씬 빨리 시작되고 표준 JVM보다 훨씬 작은 힙을 사용하여 실행할 수 있습니다.
- 섭스트레이트에서 모두 테스트되었으며 -H:+ReportUnsupportedElementsAtRuntime 플래그 없이 실행할 수 있습니다 .
- 빌드 시간 메타 데이터 처리
- 빌드시 가능한 한 많은 처리가 이루어 지므로 런타임에 실제로 필요한 클래스만 애플리케이션에 포함됩니다.
- 기존 모델에서는 애플리케이션 생애에서 애플리케이션이 배포되는 초기에 모든 클래스가 요구되었습니다.
- Quarkus 를 사용하면 프로덕션 JVM 에 로드되지 않습니다. 모든 메타 데이터 처리가 이미 완료되어 있기 때문에 결론적으로는 메모리 사용량이 줄어들고 시작 시간도 빨라집니다.
- 리플렉션 (Reflection) 사용 감소
- 가능한 한 리플렉션을 방지하여 시작 시간과 메모리 사용을 줄입니다.
- 네이티브 이미지 사전 부팅
- 네이티브 이미지로 실행하는 경우 네이티브 이미지 빌드 를 진행하면서 가능한 한 많은 프레임워크를 사전 부팅합니다. 즉, 생성 된 네이티브 이미지가 이미 대부분의 시작 코드를 실행하고 그 결과를 실행 파일로 직렬화하므로 더 빠른 시작이 가능합니다.
Container First
- 빠른 시작 (수십 밀리 초)은 컨테이너 및 Kubernetes의 미세 서비스 및 FaaS 라이브 실행의 자동 확장 및 축소를 허용합니다.
- 메모리 사용량을 낮추면 여러 컨테이너가 필요한 마이크로 서비스 아키텍처 배포시 컨테이너 밀도를 최적화 할 수 있습니다.
- 응용 프로그램 및 컨테이너 이미지 크기 축소
TomEE vs SpringBoot vs Quarkus
Platform | Build Time (s) | Build Time with tests (s) | Start Time (s) | Size (MB) |
Apache TomEE 8.0.0-M2 | 6,178 | 15,304 | 4,993 | 44 |
Spring-boot 2.1.3 | 3,358 | 13,348 | 6,799 | 46,9 |
Quarkus 0.11.0 | 2,533 | 7,153 | 0,767 | 23.4 |
(source : TomEE vs SpringBoot vs Quarkus – https://brunobat.com/2019/03/12/tomee-vs-spring-boot-vs-quarkus/ )
Quarkus로 테스트 한 빌드는 다른 환경에 비해 절반의 시간이 걸립니다. 빌드된 애플리케이션의 크기도 다른 2개의 절반입니다.
시작 시간은 비교하기 어려울 만큼 짧은 시간이 걸립니다.
더 중요한 것은 GraalVM과 함께 원시 코드를 사용하면이 시작 시간을 더 줄일 수 있습니다.
특징
지금까지 Java 어플리케이션은 JavaVM의 시작 시간 오버 헤드 등이 걸리기 때문에 경량 컨테이너 환경을 충분히 살리는 것이 어렵다고 생각했습니다.
그러나 Quarkus는 GraalVM을 사용하여 네이티브의 바이너리를 작성하여 빠르게 애플리케이션을 시작할 수 있도록 하는 프레임워크입니다.
간단하게 설명하면 Java 소스 코드를 GraalVM 을 이용하여 Linux의 Native 바이너리를 만들고 Linux 바이너리를 컨테이너에서 시작하여 지금까지 Java 의 가장 큰 단점이였던 시작 시간을 대폭 단축 할 수 있습니다.
이 바이너리는 표준 Java VM과 다른 VM 구현으로 Substrate VM이라는 것이 포함되어 있으며, 동작에 별도 Java VM이 설치되어있을 필요 없습니다.
바이너리의 크기 외에도 런타임 시작 속도, CPU 사용량, 메모리 사용량 등을 Java VM에 비교하면 대부분의 경우 몇 배 개선된 것을 확인할 수 있습니다.
Red Hat의 테스트에서는 간단한 데모 애플리케이션이 0.008 초에서 시작한 것으로 소개되어 있습니다.
Quarkus 소개 자료
Java 애플리케이션 코드에서 네이티브 바이너리를 생성하고 컨테이너화함으로써 컨테이너와 Kubernetes 환경에 최적화 된 빠르게 시작하고 메모리 소비량도 적은 애플리케이션 실행 파일을 만들수 있는 것입니다.
클라우드 고유의 Enterprise Java를 한 차원 높은 수준으로 끌어 올렸으며, 특히 애플리케이션 시작 시간과 관련해서는 이전에는 불가능했던 시나리오를 지원합니다.
정리하자면
Quarkus는 Java 애플리케이션 코드에서 네이티브 바이너리를 생성하고 컨테이너화함으로써 컨테이너와 Kubernetes 환경에 최적화 된 빠르게 시작하고 메모리 소비량도 적은 애플리케이션 실행 파일을 만들수 있는 것입니다.
클라우드 고유의 Enterprise Java를 한 차원 높은 수준으로 끌어 올렸으며, 특히 애플리케이션 시작 시간과 관련해서는 이전에는 불가능했던 시나리오를 지원합니다.
References & Related Links
- TomEE vs SpringBoot vs Quarkus – https://brunobat.com/2019/03/12/tomee-vs-spring-boot-vs-quarkus/
- https://quarkus.io/
- Introducing Quarkus: a next-generation Kubernetes native Java framework – https://developers.redhat.com/blog/2019/03/07/quarkus-next-generation-kubernetes-native-java-framework/
- Quarkus: Why compile to native? – https://developers.redhat.com/blog/2019/03/29/quarkus-why-compile-to-native/
- Quarkus : CONTAINER FIRST – https://quarkus.io/vision/container-first
- QUARKUS – GET STARTED – https://quarkus.io/get-started/