이번 포스팅에서는 구글 클라우드의 아론 완잘라가 진행한
Google Cloud Next ’23 개발자 세션 내용을 살펴보겠습니다.
Java 개발자들에게 성능 최적화는 평생 안고 가야 할 숙제와도 같은데요.
아론 완잘라는 이런 성능 최적화 아젠다를 클라우드 기반 서버리스(Serverless) 환경을 기준으로 바라보았습니다.
*본 포스팅은 주요 Google Cloud Next ’23 개발자 세션 내용을 요약하여 다루었습니다.
최적화의 세계로 초대
아론 완잘라는 ‘최적화’라는 용어가 상당히 광범위하다고 설명했는데요. Java 애플리케이션은 배포 환경에 따라 최적화 고려 대상이 좀 다릅니다. 온프레미스 환경에서는 코드 및 알고리즘, 자원(CPU와 메모리 등 하드웨어 및 운영체제), 데이터베이스 같은 연계 시스템 등을 고려합니다.
클라우드 기반 서버리스 환경도 크게 다를 것은 없습니다. 다만 차이가 있다면 클라우드 기반 서버리스 환경의 특성을 고려해야 합니다. 여기는 오토스케일링, 상태 비저장(Statelessness), 지속적 통합과 배포(CI/CD), 분산 컴퓨팅과 마이크로서비스 아키텍처 등을 잘 살펴야 합니다. 예나 지금이나 Java 애플리케이션 성능 최적화는 본질은 같지만, 환경에 따른 차이가 존재한다고 볼 수 있습니다.
아론 완잘라는 클라우드 환경에서 Java 애플리케이션의 성능 최적화가 필요한 세 영역으로 빌드 시간, 런타임, 그리고 시작 시간을 강조했습니다: 각각의 영역은 서로 다른 접근 방식이 필요하며 이에 따라 최적화 전략이 달라질 수 있습니다.
- 최적화 포인트 #1: 빌드는 애플리케이션의 코드를 모아서 실행 가능한 파일(이미지나 JAR 파일)로 만드는 과정을 말합니다. 빌드 시간이 길면 개발 프로세스가 느려집니다. 특히, CI/CD 환경에서는 빌드 시간이 전체 소프트웨어 배포 시간에 큰 영향을 미칩니다. 따라서 불필요한 라이브러리 제거, 효율적인 빌드 도구 사용, 캐시 활용 등을 통해 빌드 프로세스를 빠르고 효율적으로 만들어야 합니다.
- 최적화 포인트 #2: 다음으로 런타임 최적화는 애플리케이션이 실행되고 있는 동안의 성능을 개선하는 것을 말합니다. 런타임 성능은 사용자 경험과 직결되어 있기에 느린 응답 시간은 사용자 경험에 좋지 않은 영향을 끼칠 수 있습니다. 따라서 JVM 최적화, 메모리 관리, 효율적인 알고리즘 사용, 적절한 데이터 구조 선택 등을 통해 성능을 높여야 합니다.
- 최적화 포인트 #3: 시작 시간 최적화는 애플리케이션이 시작되고 사용 가능 상태가 되기까지 시간을 단축하는 것을 뜻합니다. 서버리스 환경과 같이 빠른 시작이 중요한 상황에서는, 시작 시간이 전체 성능에 큰 영향을 미칩니다. 사용자가 서비스를 요청하고 있을 때 애플리케이션이 빠르게 응답할 수 있어야 합니다. 따라서 경량화된 프레임워크 사용, 불필요한 초기화 작업 최소화, 빠른 시작을 지원하는 기술(예: GraalVM의 네이티브 이미지 컴파일) 사용 등을 통해 애플리케이션의 시작 시간을 줄여야 합니다.
📈 성능 최적화를 위한 플로우 차트
아론 완잘라는 성능 문제를 진단하는 데 사용하는 플로우 차트를 공유하면서, 이를 통해 개발자들이 성능 문제의 근본 원인을 파악하고 적절한 해결책을 찾을 수 있다고 설명했습니다. 여기서 그는 빌드 시간 최적화와 런타임 최적화의 중요성을 강조했습니다.
참고로 플로우 차트를 사용하는 목적은 성능 문제의 원인을 체계적으로 분석하고, 문제의 유형에 따라 적합한 최적화 전략을 적용하는 것입니다. 이는 개발자들이 복잡한 성능 문제를 더 효과적으로 관리하고, 더 나은 성능의 Java 애플리케이션을 개발할 수 있도록 도와줍니다.
CRaC과 클래스 데이터 공유
한편 아론 완잘라는 CRaC(Coordinated Restore at Checkpoint)과 클래스 데이터 공유라는 두 가지 주요 최적화 기술에 관해 설명했습니다. CRaC는 Java 애플리케이션을 미리 사용 준비가 되어 성능이 최적화된 (Warmed Up)’ 상태에서 복원할 수 있는 기술입니다. 여기서 미리 사용 준비가 되어 성능이 최적화되었다는 것은 애플리케이션이 이미 실행 중이며, 메모리에 로드된 상태, JVM 최적화가 일부 적용된 상태 등을 의미합니다. 애플리케이션이 실행 중일 때, 특정 시점에 체크포인트가 생성됩니다. 이 체크포인트는 애플리케이션의 상태를 저장한 스냅샷입니다. 나중에 이 체크포인트를 사용하여 애플리케이션을 동일한 상태로 빠르게 복원할 수 있습니다.
다음으로 클래스 데이터 공유는 공유 아카이브를 사용하여 Java 애플리케이션의 시작 시간과 런타임 메모리 사용량을 줄이는 기술입니다. 이 기술은 공통으로 사용되는 클래스와 리소스를 사전에 컴파일하고 이를 공유 아카이브에 저장합니다. 다양한 Java 애플리케이션 또는 인스턴스가 이 공유 아카이브를 사용하여 필요한 클래스를 빠르게 로드할 수 있습니다.
CRaC와 클래스 데이터 공유 같은 기술은 복잡한 Java 애플리케이션 또는 대규모 분산 서버 환경에서 성능과 자원 효율성을 개선하는 데 큰 도움이 된다고 합니다.
네이티브 이미지 컴파일
마지막으로 아론 완잘라는 네이티브 이미지 컴파일(Native Image Compilation)에 대해 이야기했습니다. 기존의 JVM은 ‘한 번 작성하고 어디서나 실행(Run Anywhere)’이라는 원칙을 따릅니다. 즉, Java 애플리케이션은 JVM 위에서 동작하며, 이 JVM이 다양한 하드웨어와 운영 체제에서 애플리케이션을 실행할 수 있게 해줍니다. 반면에 네이티브 이미지 컴파일 접근법은 JVM을 사용하지 않고, 대신 애플리케이션을 특정 아키텍처(예: 특정 CPU, 운영 체제)에 직접 맞춤 컴파일합니다. 이 과정을 통해 생성된 실행 파일은 해당 시스템에서 네이티브로 실행됩니다.
네이티브 이미지 컴파일을 통해 생성된 애플리케이션은 JVM을 초기화하고 Java 바이트코드를 네이티브 코드로 변환하는 과정 없이 바로 실행됩니다. 이는 애플리케이션의 시작 시간을 크게 단축하고, 전반적인 실행 성능을 높입니다. 장점만 있는 것은 아닙니다. 긴 빌드 시간과 높은 리소스 요구 등 반대급부로 손해를 봐야 하는 부분도 있습니다.
애플리케이션의 시작 시간이 중요하거나 리소스 제한 환경에서 실행되는 경우 네이티브 이미지 컴파일이 유리할 수 있지만, 장기 실행 워크로드나 동적 기능이 중요한 경우에는 전통적인 JVM 기반 실행이 더 적합할 수 있습니다.
세미나 영상 다시 보기
오늘은 Google Cloud Next ’23에서 진행한 아론 완잘라의 세션을 간단히 요약해 보았습니다.
아론 완잘라의 세션 영상과 함께 그가 쓴 블로그를 참조하면 클라우드 기반 서버리스 환경에서 자바 성능 최적화에 대해 더욱 자세히 이해하실 수 있습니다.
더 자세한 내용이 궁금하시면 메가존소프트로 문의해 주세요! 👉 메가존소프트 문의 바로 가기