이 기사에서는 Apache Kafka 환경을 비교하는 연구를 제시합니다. 궁극적인 목표는 가장 효과적인 설정을 찾고 최고의 가격 대비 성능을 달성하는 것입니다.
우리의 데이터 플랫폼은 다른 시장 솔루션과 경쟁하면서 대규모 데이터 세트에 대한 분석 플랫폼을 구축하기 위한 관리 서비스를 제공합니다. 경쟁력을 유지하기 위해 우리는 정기적으로 내부 연구를 수행하여 강점을 파악하고 개선하여 더 나은 거래를 보장합니다. 이 기사에서는 그러한 연구 중 하나를 소개합니다. 현재 우리 플랫폼은 AWS와 GCP를 클라우드 공급자로 지원합니다. 둘 다 여러 컴퓨팅 세대와 2개의 CPU 아키텍처(Intel, AMD 및 ARM의 x86)를 제공합니다. 저는 최신 프로세서에서 새 버전의 성능을 평가하기 위해 다양한 JVM(Java Virtual Machine)을 사용하여 이러한 설정을 비교합니다.
TL;DR을 원한다면: ARM이 흔들립니다. 현대의 값비싼 건축물이 항상 "더 나은" 것을 의미하는 것은 아닙니다. 결과로 바로 이동하거나 계속해서 방법론 및 설정에 대해 자세히 알아볼 수 있습니다.
자체 서비스로 성능 테스트를 고려했지만 아직 지원하지 않는 다른 환경에서 비교하고 싶었습니다. 새로운 가상 머신, 지역, 심지어 다른 클라우드 제공업체도 확인하고 싶었습니다. 그래서 저는 다양한 기본 컨테이너 이미지와 함께 기본 Kafka를 사용하는 장난감 프로젝트를 구현하는 것부터 시작했습니다. 이렇게 하면 특정 하드웨어에서 벤치마크 도구를 실행하고 성능을 측정할 수 있습니다.
가장 흥미로운 결과를 확인하기 위해 다양한 구성을 테스트하는 것을 목표로 합니다. 이를 위해 테스트 매트릭스의 아이디어를 사용하여 초기 결과를 필터링합니다. 성능을 더욱 개선하기 위해 perf 및 eBPF와 같은 도구를 사용하여 이러한 결과를 심층적으로 분석하겠습니다.
먼저 테스트 목표를 설명하겠습니다. 저는 OpenJDK JVM에 대한 많은 경험을 가지고 있지만 현재는 Microsoft, Amazon 및 기타 회사의 대안이 많이 있습니다. 예를 들어 Amazon Correto에는 AWS에 최적화된 추가 기능과 패치가 포함되어 있습니다. 대부분의 고객이 AWS를 사용하기 때문에 테스트에 Amazon Correto를 포함시켜 이러한 JVM이 해당 플랫폼에서 어떻게 작동하는지 확인하고 싶었습니다.
첫 번째 비교를 위해 다음 버전을 선택했습니다.
버전이 정의되면 Amazon Correto 및 OpenJDK를 사용하여 Kafka 이미지를 빌드하기 위한 몇 가지 스크립트를 준비했습니다.
벤치마킹 테스트에서는 특정 성능 지표에 초점을 맞추도록 Kafka 설정을 변경했습니다. [JVM] x [instance_type] x [architecture] x [cloud_provider] 의 다양한 조합을 테스트하고 싶었기 때문에 네트워크 연결 및 디스크 성능의 영향을 최소화하는 것이 중요했습니다. 데이터 저장을 위해 tmpfs를 사용하여 컨테이너를 실행하여 이 작업을 수행했습니다.
podman run -ti \ --network=host \ --mount type=tmpfs,destination=/tmp \ kfbench:3.6.1-21.0.2-amzn-arm64
당연히 이 설정은 프로덕션용은 아니지만 CPU와 메모리 병목 현상을 격리하는 것이 필요했습니다. 가장 좋은 방법은 테스트에서 네트워크 및 디스크 영향을 제거하는 것입니다. 그렇지 않으면 해당 요인으로 인해 결과가 왜곡될 수 있습니다.
지연 시간을 최소화하고 재현성을 높이기 위해 동일한 인스턴스에서 벤치마크 도구를 사용했습니다. 또한 호스트 네트워크 구성 없이 cgroup 격리 가상 네트워크를 사용하여 테스트를 시도했지만 이로 인해 불필요한 대기 시간이 추가되고 패킷 전달을 위한 CPU 사용량이 증가했습니다.
tmpfs는 메모리를 동적으로 할당하고 조각화 및 대기 시간을 유발할 수 있지만 테스트에는 적합했습니다. 대신 메모리를 정적으로 할당하고 이러한 문제를 방지하는 ramdisk를 사용할 수도 있었지만 tmpfs가 구현하기 더 쉬웠고 여전히 우리가 원하는 통찰력을 제공했습니다. 우리의 목적에 따라 적절한 균형을 이루었습니다.
또한 메모리에서 데이터를 더 자주 제거하기 위해 몇 가지 추가 Kafka 설정을 적용했습니다.
############################# Benchmark Options ############################# # https://kafka.apache.org/documentation/#brokerconfigs_log.segment.bytes # Chaged from 1GB to 256MB to rotate files faster log.segment.bytes = 268435456 # https://kafka.apache.org/documentation/#brokerconfigs_log.retention.bytes # Changed from -1 (unlimited) to 1GB evict them because we run in tmpfs log.retention.bytes = 1073741824 # Changed from 5 minutes (300000ms) to delete outdated data faster log.retention.check.interval.ms=1000 # Evict all data after 15 seconds (default is -1 and log.retention.hours=168 which is ~7 days) log.retention.ms=15000 # https://kafka.apache.org/documentation/#brokerconfigs_log.segment.delete.delay.ms # Changed from 60 seconds delay to small value to prevent memory overflows log.segment.delete.delay.ms = 0
변경 사항을 요약하면 다음과 같습니다.
이 구성은 프로덕션 용도에는 적합하지 않지만 관련 없는 요소의 영향을 줄이기 때문에 벤치마크 테스트에는 중요합니다.
이 기사를 작성하는 시점을 기준으로 DoubleCloud에서는 다음과 같은 주요 세대의 컴퓨팅 리소스를 지원합니다.
Graviton 프로세서의 경우 다음을 지원합니다.
또한 Ampere Altra의 Graviton 대신 GCP에서 t2a 인스턴스를 테스트했습니다. AWS의 제한된 지역 지원으로 인해 고객에게 이러한 기능을 제공하지 않지만 성능 비교를 위해 벤치마크에 포함시켰습니다. 귀하가 "올바른" 지역 중 하나에 있다면 이는 좋은 선택이 될 수 있습니다.
벤치마킹을 위해 franz-go 라이브러리와 example 을 기반으로 하는 경량 도구를 개발했습니다. 이 도구는 자체적으로 병목 현상이 발생하지 않으면서 Kafka를 효율적으로 포화시킵니다.
librdkafka는 신뢰성과 인기로 잘 알려져 있지만 cgo의 잠재적인 문제 때문에 사용을 피했습니다.
Kafka는 토픽을 여러 파티션으로 나누어 브로커 전체에 워크로드를 수평으로 효율적으로 분산할 수 있는 확장성으로 잘 알려져 있습니다. 그러나 저는 가격 대비 성능 비율에 중점을 두고 단일 코어 성능을 평가하는 데 집중했습니다.
따라서 테스트에서는 개별 핵심 기능을 최대한 활용하기 위해 단일 파티션으로 주제를 활용했습니다.
각 테스트 케이스에는 두 가지 유형이 포함되었습니다.
주제 파티션 스레드를 완전히 포화시키기 위해 평균 고객 사례보다 큰 8KB 메시지를 사용했습니다.
저는 다양한 아키텍처를 평가하기 위해 합성 효율성 지표를 사용하여 다양한 테스트 사례를 비교하는 일련의 플롯을 제시합니다. 이 지표는 Kafka 브로커에 수집할 수 있는 수백만 개의 행을 백분율로 수량화하여 아키텍처 비용 효율성을 간단하게 평가합니다.
클라우드 공급자의 추가 할인으로 인해 실제 결과가 달라질 수 있다는 점을 인정하는 것이 중요합니다. 가능할 때마다 테스트는 두 클라우드 제공업체 모두 프랑크푸르트에서 수행되었습니다(또는 인스턴스 유형 옵션이 제한된 경우 네덜란드에서).
모든 차트에서 나는 공급자가 사용하는 것과 동일한 인스턴스 이름을 사용합니다. 인스턴스는 먼저 클라우드 제공업체(AWS, 그다음 GCP)별로 정렬된 다음 세대별로(오래된 것부터 최신 것까지) 정렬됩니다.
원시 형식이기는 하지만 전체 결과는 내 포괄적인 벤치마킹 시트 에서 확인할 수 있습니다. 여기서는 대기 시간 및 대역폭 수치, 다양한 JVM의 비교 성능을 포함하여 이 기사에 제시된 것보다 더 많은 데이터를 찾을 수 있습니다.
2019년 3분기에 출시된 AMD EPYC 7571을 탑재한 m5a 세대 기반의 "1세대" s1 인스턴스는 레거시 옵션입니다. 프랑크푸르트의 옵션 중에서 효율성이 가장 낮고 가장 느립니다. 비용은 주문형 시간당 약 ~0.2080€입니다. 시간당 ~0.2070€의 비용이 드는 최신 s2 제품군으로 전환하면 기본적으로 동일한 가격으로 효율성이 두 배 향상됩니다. 분석 애플리케이션의 쿼리 시간과 수집 속도를 향상하려면 고객이 보다 비용 효율적이고 성능이 뛰어난 옵션으로 마이그레이션하는 것이 좋습니다.
g1 제품군은 Graviton 2를 기반으로 하며 역사적으로 좋은 가치를 제공했지만 AMD 프로세서를 탑재한 최신 s2 제품군은 이제 Apache Kafka의 효율성 수준과 일치합니다. 약간 더 낮은 대역폭과 한계 가격 이점을 제공함에도 불구하고 g1 제품군은 이제 새로운 옵션에 비해 오래된 것으로 간주됩니다.
Graviton 3로 구동되는 g2 제품군은 뛰어난 효율성으로 인해 최고의 권장 제품으로 돋보입니다. 특정 시나리오에서 s2 및 i2 제품군보다 최대 39% 성능이 뛰어나 거의 모든 지역에서 비용 효율적인 솔루션을 제공하므로 대부분의 Apache Kafka 사용 사례에 이상적입니다. Kafka의 일반적인 IO 바인딩 특성을 고려할 때 계산 효율성을 최적화하는 것은 비용 절감에 매우 중요합니다. 저는 arm64 아키텍처를 채택하는 경향이 증가하는 것을 목격했으며, 클러스터의 거의 절반이 이미 이 최신 기술을 활용하고 있습니다.
테스트 결과 모든 새로운 AMD 또는 Intel 프로세서는 전체 처리량 및 대기 시간 측면에서 향상되는 것으로 나타났습니다. 그럼에도 불구하고 최신 m6 및 m7 세대의 효율성 향상은 정체되었습니다. 테스트에 따르면 m7 세대도 일부 지역에서는 대기 시간이 더 낮을 가능성이 있지만 g2 제품군에 비해 효율성이 부족합니다.
m7a 제품군은 처리량과 대기 시간 측면에서 Intel과 이전 AMD 세대를 모두 능가하는 저지연 애플리케이션에 탁월합니다. 보편적으로 사용할 수는 없지만 이 아키텍처는 성능 향상에 대한 AMD의 발전을 반영합니다. 해당 지역에서 액세스할 수 있는 경우 우수한 결과를 얻으려면 m7a를 고려하십시오.
GCP 인스턴스는 일반적으로 AWS 대안보다 효율성이 낮습니다. 고객은 일반적으로 분석 애플리케이션의 비용 효율성 때문에 GCP를 선호하므로 청구서 비용이 낮아지기 때문에 이는 저에게 큰 통찰이었습니다. sg1 제품군은 AWS s2 제품군과 비슷한 n2 표준 세대를 활용합니다. 그러나 이 비교를 다른 인스턴스 유형으로 확장하려는 시도는 특히 c3 및 n2 세대의 경우 지역 가용성으로 인해 제한되었습니다.
GCP의 Tau 프로세서를 사용하는 Arm 인스턴스는 Graviton 2에 비해 5~7% 향상된 효율성을 제공하므로 해당 지역에서 사용 가능한 경우 합리적인 비용 절감 옵션이 됩니다. arm 인스턴스에 대한 GCP 지원은 4개 지역으로 제한되지만 g1 제품군과 비슷한 성능과 효율성을 제공합니다.
Apache Kafka 클러스터는 VM을 지속적으로 사용하므로 지속 사용 할인을 활용하면 최대 20% 할인이 가능합니다. 이로 인해 Ampere Altra와 같은 훨씬 오래된 컴퓨팅 성능이 효율성 측면에서 Graviton 3와 경쟁하게 됩니다. 하지만 여기서는 추가 AWS 할인도 적용될 수 있기 때문에 직접적인 비교가 까다롭습니다.
저는 ARM 아키텍처의 최신 JVM 버전을 사용하면 상당한 개선이 있을 것이라고 생각했습니다. 그러나 openjdk-11과 corretto-11은 이미 ARM에 상당히 최적화된 것 같습니다. 최신 버전의 Kafka에는 Java 17 이상이 필요하기 때문에 Java 17로 전환했는데, 그 결과 벤치마크에서 약 4~8%의 성능 향상이 있었습니다.
또한 21.0.2-amzn은 새로운 인스턴스 유형에서 추가로 10~20% 성능 향상을 제공하는 유망한 것으로 보입니다.
때때로 저는 생산 클러스터에 대한 최적의 솔루션을 찾고 유용한 통찰력을 수집하기 위해 내부 연구를 수행합니다. ARM 아키텍처로의 전환은 비용을 절감하고 에너지 사용량을 줄이므로 관리형 서비스에 유리합니다.
ARM을 사용하면 Apache Kafka용 관리 서비스와 ClickHouse용 관리 서비스 모두의 성능과 비용 효율성이 향상되어 이미 이점이 입증되었습니다. 이 연구는 테스트 매트릭스를 개선하고 추가 최적화를 위한 가장 효율적인 환경과 영역을 식별하는 데 도움이 되었습니다. 우리는 항상 내부적으로 조정하고 개선하고 있으며 우리의 지식을 커뮤니티와 공유하게 되어 기쁘게 생각합니다. 계속 지켜봐 주시기 바랍니다!