GraalVM 기반 네이티브 카프카 브로커 도커 이미지

Victor Park
SPITHA Blog
Published in
6 min readOct 19, 2023

by JW.Song

카프카는 Scala와 Java로 개발 되어 있으며 JVM 기반에서 작동한다. JVM도 일종의 가상머신으로 애플리케이션 구동 시 성능에 영향을 미치는 오버헤드를 갖는다. 특히 자바 컴파일러는 컴파일 결과를 여러 종류의 시스템에서 변경 없이 동작할 수 있도록 머신 코드 대신 바이트 코드라는 중간 형태로 생성한다. 이 바이트코드를 JVM에서 애플리케이션이 실행되는 시스템에 맞는 머신 코드로 변환하여 실행하게 된다.

자바 애플리케이션을 실행하면 먼저 JVM이 구동이 되고 JVM에서 실제 애플리케이션 클래스를 로드 하여 머신 코드로 변환하면서 실행하게 된다. 따라서 golang이나 C/C++처럼 머신 코드로 컴파일된 애플리케이션에 비해 상대적으로 느린 실행 속도를 갖게 된다. 이런 문제를 해결하기 위해 [KIP-974]에서 카프카 브로커를 GraalVM을 이용하여 머신 코드로 컴파일하여 도커 이미지로 제공하는 것을 논의 하고 있다.

Docker Image for GraalVM based Native Kafka Broker

Motivation

기존 Java 기반 Kafka 브로커는 시작하는 데 몇 초가 걸린다. 프로덕션 워크로드에서 장기간 실행되는 브로커의 중요도에는 영향을 미치지 않지만, 로컬 개발 중에 애플리케이션의 단위 테스트를 위해 수백 개의 브로커를 인스턴스 화하는 개발자를 괴롭힐 수 있다.

이 KIP는 1초 미만의 시작 시간과 최소한의 메모리 사용량으로 브로커를 시작할 수 있는 실험적인 Apache Kafka 도커 이미지를 제공하는 것을 목표로 하며, GraalVM 기반 네이티브 Kafka 바이너리를 활용한다.

이 KIP를 통해 네이티브 카프카 아티팩트를 공식화하는 데 영감을 준 Ozan Gunalp의 kafka native 작업 덕분이다.

GraalVM 기반 네이티브 카프카 브로커를 사용한 브로커 시작 시간, CPU 사용량 및 메모리 사용 공간

GraalVM에는 Java 애플리케이션의 사전 컴파일을 통해 네이티브 독립 실행형 실행 파일을 빌드할 수 있는 기능이 있다. 이러한 네이티브 실행 파일은 일반적으로 메모리 사용 공간이 더 작고 JVM 실행 파일보다 빠르게 시작된다.

GraalVM 기반 Kafka 브로커는 JVM 기반 브로커와의 벤치마킹에서 훨씬 더 빠른 시작 시간과 적은 RAM 소비를 보여주었다. 자세한 내용은 다음과 같다.

평균 카프카 브로커 시작 시간 GraalVM과 JVM 비교

  • JVM(기본 구성)을 사용한 평균 Kafka 서버 시작 시간: ~1150ms — 1200ms
  • 다음은 GC와 PGO에 따른 GraalVM 기반 Native Kafka Broker의 시작 시간 비교
Startup times of GraalVM based Native Kafka Broker

GraalVM과 JVM의 카프카 브로커 CPU 및 메모리 사용량 비교

Kafka Broker using JVM
Native-Binary-serialGC
Native-Binary-G1GC

측정 결과:

  • GraalVM 브로커의 시작 시간은 JVM 브로커의 시작 시간의 약 1/9
  • GraalVM 브로커는 CPU 스파이크가 관찰되지 않았지만, JVM 브로커는 브로커가 시작될 때와 부하 테스트가 시작될 때 모두 급격한 스파이크가 발생
  • 메모리 사용량에서도 상당한 차이가 관찰됨. 최대 메모리 사용량은 JVM 브로커의 경우 최대 1GB까지 올라간 반면, G1GC를 사용하는 GraalVM 브로커의 경우 최대 500MB, 직렬 GC를 사용하는 GraalVM 브로커의 경우 최대
  • 250MB까지 올라감

벤치마킹 테스트 방법:

토픽을 만들고, 기본 구성을 사용하여 토픽을 생성하고 토픽에서 소비

벤치마킹에 사용되는 머신 구성:

  • 머신: m6i.2xlarge
  • 아키텍처: x86_64
  • OS: 우분투
  • Java 버전: openjdk 17.0.8 2023–07–18
  • GraalVM 네이티브 이미지 버전:
    - native-image 17.0.8 2023–07–18
    - GraalVM 런타임 환경 오라클 GraalVM 17.0.8+9.1(빌드 17.0.8+9-LTS-jvmci-23.0-b14)

공개 내용

  • 모든 Apache Kafka 릴리스에 대한 도커 이미지

제안된 변경 사항

  • 모든 Apache Kafka 릴리즈에 대한 추가 아티팩트로 도커 이미지가 추가될 예정
  • 이 도커 이미지는 GraalVM 네이티브 이미지 기반 카프카 바이너리로 구성되며 Linux 기반 AMD 및 ARM 아키텍처를 지원할 예정
  • 각 태그에 대한 새로운 도커 이미지에 대해 실행되도록 기존 Kafka 시스템 테스트 프레임워크를 확장
  • ARM 및 AMD 아키텍처 모두에 대한 Kafka 네이티브 실행 파일을 생성하기 위한 새로운 빌드 시스템이 추가됨. 이 새로운 빌드 시스템은 기존의 Java 및 Scala 기반 Kafka 빌드 시스템에 추가됨
  • Apache CI/CD 파이프라인을 확장하여 새로운 docker 이미지를 퍼블릭 DockerHub에 게시할 수 있음

호환성, 지원 중단 및 마이그레이션 계획

  • 기존 아파치 카프카 사용자에게는 네이티브 이미지 기반 카프카 도커 이미지가 새로운 기능이므로 아무런 영향이 없음
  • GraalVM 네이티브 이미지 기반 아파치 카프카 도커 이미지는 실험적인 도커 이미지가 될 것임
  • JVM과 달리 GraalVM 네이티브 이미지는 사전 컴파일을 수행하며 동적 클래스 로딩을 지원하지 않음. GraalVM 네이티브 이미지를 통한 전체 브로커 기능 지원 및 성능을 이해하려면 광범위한 테스트가 필요함. GraalVM 네이티브 이미지 기반 컨테이너는 개발 및 테스트용으로만 권장되며 프로덕션 워크로드에는 사용하지 않는 것이 좋음
  • 프로덕션용 도커 이미지의 경우 [KIP-975]를 참조하기 바람

--

--