performance-tuning

2 개의 포스트

cloudflare원문

Cloudflare의 13세대 서버 출시 - 캐시를 코어로 바꿔 엣지 컴퓨팅 성능 2배 향상 (새 탭에서 열림)

Cloudflare는 차세대 에지 컴퓨팅 성능을 2배로 끌어올리기 위해 AMD EPYC 5세대 'Turin' 프로세서를 기반으로 한 13세대(Gen 13) 서버를 도입했습니다. 기존 12세대 서버가 거대한 L3 캐시(3D V-Cache)에 의존했던 것과 달리, 13세대는 캐시 용량을 줄이는 대신 코어 수를 대폭 늘려 처리량을 극대화하는 전략을 선택했습니다. 이러한 하드웨어 변화는 Rust 기반의 새로운 요청 처리 계층인 'FL2'로의 전환이 있었기에 가능했으며, 이를 통해 캐시 의존성을 탈피하고 늘어난 코어 성능을 온전히 활용할 수 있게 되었습니다. ### AMD Turin 아키텍처의 혁신과 캐시 트레이드오프 AMD EPYC 5세대 Turin 프로세서는 단순한 코어 수 증설 이상의 아키텍처적 개선을 제공합니다. * **코어 밀도 및 효율성:** 12세대의 96코어에서 2배 늘어난 최대 192코어(384스레드)를 지원하며, Zen 5 아키텍처 적용으로 IPC(사이클당 명령어 처리 수)가 향상되었습니다. 코어당 전력 소모량은 오히려 32% 감소하여 전력 효율성이 개선되었습니다. * **메모리 대역폭 확장:** DDR5-6400 메모리를 지원하여 늘어난 코어들이 데이터를 신속하게 주고받을 수 있는 환경을 구축했습니다. * **캐시 감소의 한계:** 하지만 고밀도 설계를 위해 코어당 L3 캐시 용량은 12세대의 12MB에서 2MB로 크게 줄었습니다. 이는 캐시 로컬리티에 의존적인 기존 워크로드에 심각한 성능 병목을 일으킬 수 있는 구조적 변화입니다. ### 기존 FL1 스택에서의 성능 병목 분석 Cloudflare의 기존 NGINX 및 LuaJIT 기반 요청 처리 계층인 FL1은 줄어든 캐시 환경에서 심각한 지연 시간 문제를 노출했습니다. * **지연 시간 급증:** AMD uProf 도구 분석 결과, L3 캐시 미스 시 데이터 접근 시간이 50사이클에서 350사이클(DRAM 접근 시)로 7배 이상 증가하는 것을 확인했습니다. * **처리량과 지연 시간의 상충:** Turin 9965 프로세서에서 FL1을 실행했을 때 처리량(Throughput)은 62% 증가했지만, 높은 CPU 사용률 구간에서 지연 시간(Latency)이 50% 이상 늘어나는 결과가 나타나 실제 서비스 적용에 부적합 판정을 받았습니다. ### 하드웨어 튜닝 및 PQOS를 통한 최적화 실험 하드웨어의 한계를 극복하고 최적의 성능 지점을 찾기 위해 AMD와 협업하여 다양한 최적화 기술을 적용했습니다. * **하드웨어 튜닝:** 프리페처(Prefetcher) 및 데이터 패브릭(DF) 프로브 필터 조정 등을 시도했으나 성능 향상 폭은 미미했습니다. * **AMD PQOS 적용:** L3 캐시와 메모리 대역폭을 미세 조정할 수 있는 PQOS(Platform Quality of Service) 기술을 사용했습니다. * **NUMA 인지 구성:** 특정 CCD(Core Complex Die)를 FL 전용으로 할당하는 NUMA 인지형 코어 어피니티 설정을 통해, 지연 시간을 허용 범위 내로 유지하면서도 약 15%의 추가 처리량 이득을 확보하는 데 성공했습니다. ### Rust 기반 FL2 스택을 통한 성능 해방 결국 하드웨어의 잠재력을 100% 끌어올린 핵심 동력은 소프트웨어 재작성이었습니다. * **캐시 의존성 탈피:** Rust로 작성된 FL2는 효율적인 메모리 관리와 현대적인 설계를 통해 캐시 크기에 민감하게 반응하던 FL1의 한계를 극복했습니다. * **선형적 성능 확장:** FL2 도입을 통해 Turin 프로세서의 192코어 성능을 지연 시간 하락 없이 온전히 사용할 수 있게 되었으며, 이는 Cloudflare 에지 네트워크의 총 소유 비용(TCO) 최적화로 이어졌습니다. 인프라의 세대 교체 시 하드웨어 사양(코어 수, 캐시 용량 등)의 변화가 기존 소프트웨어 스택의 설계 원칙과 충돌할 수 있습니다. Cloudflare의 사례처럼 하드웨어 성능 최적화가 한계에 다다랐을 때는, Rust와 같은 현대적인 언어로 소프트웨어 아키텍처를 재설계함으로써 하드웨어의 물리적 변화를 성능 도약의 기회로 전환하는 전략이 필요합니다.

datadog원문

우리 작업 시스템에서 쿠버네티스 오버헤드를 최소화한 방법 (새 탭에서 열림)

Datadog은 기존 작업 시스템을 Kubernetes로 이전하는 과정에서 CPU 사용량은 증가하고 작업 처리 속도는 40-50% 저하되는 성능 퇴행 문제를 겪었습니다. 이를 해결하기 위해 VM과 Kubernetes 간의 정밀한 비교 실험을 설계하고, 지표 측정 방식과 리소스 할당(Resource Requests) 설정을 최적화하여 성능을 이전 수준으로 복구했습니다. 본 분석을 통해 Kubernetes 오버헤드의 실체를 파악하고, 고성능 워크로드를 위한 포드 배치 전략을 도출했습니다. ### 실험 환경의 통제와 정렬 * **환경 변수 통일**: 성능 차이의 원인을 정확히 규명하기 위해 VM과 Kubernetes 클러스터의 인스턴스 유형(c5.2xlarge), 커널 버전(3.13.0-141), 실행 스크립트를 동일하게 맞추어 비교 대상을 단일화했습니다. * **배치 구조 최적화**: 기존 VM 방식과 유사하게 하나의 포드 내에 하나의 부모 프로세스와 그 자식 워커들을 배치하여, 노드당 부모 프로세스 수와 포드 수가 일치하도록 구성했습니다. ### 측정 지표의 재정의: Idle CPU의 중요성 * **Load Average의 한계**: Kubernetes에서는 상태 확인 등을 위한 배경 프로세스가 빈번하게 실행되는데, 이는 실제 CPU 사용량과 무관하게 Load Average 수치를 비정상적으로 높여 시스템이 바쁜 것처럼 오해하게 만듭니다. * **Idle CPU 활용**: 프로세스 개수가 아닌 '실제 CPU가 일하지 않는 시간'을 측정하는 Idle CPU 지표를 선택함으로써, 시스템의 남은 용량을 더 정확하게 파악하고 성능 분석의 신뢰도를 높였습니다. * **처리량(Throughput) 중심**: 배치 작업의 특성에 맞춰 지연 시간(Latency)보다는 30초당 완료된 작업 수라는 처리량 지표를 핵심 성능 지표로 설정했습니다. ### 리소스 요청(Resource Requests) 및 스케줄링 튜닝 * **스케줄링 병목 해결**: 초기에 각 포드가 1 Core CPU를 요청하도록 설정했을 때, 노드당 4개의 포드만 배치되는 과소 활용 문제가 발생했습니다. 목표치인 노드당 6개 포드 배치를 위해 CPU 요청을 100m으로, 메모리 요청을 500MB로 대폭 낮췄습니다. * **단일 리소스 기준 권장**: 여러 리소스(CPU, 메모리 등)의 요청 값을 모두 엄격하게 잡으면 스케줄링이 복잡해지므로, 하나의 주된 리소스를 기준으로 배치를 유도하고 나머지는 실제 필요량에 가깝게 설정하는 것이 효율적임을 확인했습니다. * **Request와 Limit의 구분**: `request`는 스케줄링을 위한 최소 보장치이며, 실제 실행 중의 제약은 `limit`이 담당하므로 `request`를 낮추는 것이 실행 성능에 부정적인 영향을 주지 않는다는 점을 활용했습니다. ### 포드별 오버헤드의 실체 분석 * **프로세스 구조**: `pstree`를 통해 분석한 결과, 포드당 오버헤드는 주로 컨테이너 런타임인 `containerd-shim`에서 발생했습니다. * **CPU 및 메모리 비용**: 실험 결과 포드당 CPU 오버헤드는 무시할 수 있는 수준이었으며, 메모리는 포드당 약 24MB(containerd-shim 및 pause 컨테이너 포함) 수준으로 측정되었습니다. * **결론적 선택**: 오버헤드가 크지 않기 때문에, 관리 효율성을 위해 포드 하나에 여러 부모 프로세스를 억지로 집어넣기보다 '포드당 1 부모 프로세스' 구조를 유지하는 것이 더 유리하다는 결론을 내렸습니다. Kubernetes로 이전 시 발생하는 성능 저하는 플랫폼 자체의 문제라기보다 잘못된 리소스 요청 설정과 지표 해석에서 기인하는 경우가 많습니다. 노드당 포드 밀도를 최적화하기 위해 `Resource Requests`를 전략적으로 낮게 설정하고, 시스템의 부하를 판단할 때는 Load Average 대신 Idle CPU를 관찰함으로써 VM에 근접한 성능을 확보할 수 있습니다.