테스트 시간을 50 (새 탭에서 열림)
개발 효율성을 저해하는 길고 불안정한 CI 파이프라인 문제를 해결하기 위해, 테스트와 소스 코드 간의 의존성을 분석하여 변경된 코드와 관련된 테스트만 선택적으로 실행하는 '테스트 영향 분석(Test Impact Analysis)' 기술이 주목받고 있습니다. Datadog은 Ruby 환경에서 이를 실현하기 위해 성능 저하를 최소화하면서도 기존 도구와 호환되는 전용 라이브러리를 개발하였으며, 이는 전체 테스트 시간을 절반 수준으로 단축하는 성과를 거두었습니다. 이 과정에서 개발 팀은 Ruby 내장 모듈의 한계를 극복하기 위해 C 확장을 통한 저수준 인터프리터 이벤트 활용 방식을 채택했습니다. ## 테스트 영향 분석(TIA)의 개념과 필요성 - 소프트웨어 규모가 커짐에 따라 전체 테스트 수트 실행 시간은 비대해지며, 코드 변경과 무관한 '불안정한 테스트(Flaky tests)'로 인해 CI가 실패하는 빈도가 높아집니다. - 테스트 영향 분석은 각 테스트가 실행될 때 접근하는 소스 파일 목록을 동적으로 맵핑하여 저장하는 기술입니다. - Git 커밋 시 변경된 파일과 맵핑된 파일 목록에 교집합이 있는 테스트만 실행함으로써, 불필요한 리소스 낭비를 줄이고 파이프라인의 안정성을 높일 수 있습니다. - Datadog의 'Intelligent Test Runner'는 이러한 원리를 바탕으로 정확성, 성능, 사용자 투명성을 핵심 가치로 설계되었습니다. ## 기존 Ruby 솔루션의 성능 한계 - **내장 Coverage 모듈:** Ruby 3.1에서 추가된 resume/suspend 메서드를 통해 테스트별 커버리지를 측정할 수 있으나, `simplecov`와 같은 기존 도구와 충돌하며 약 300% 수준의 매우 높은 성능 오버헤드가 발생합니다. - **TracePoint API:** 코드 실행 시 이벤트를 구독하는 표준 API로 구현이 용이하고 호환성도 뛰어나지만, 순수 코드 실행 위주의 벤치마크(RuboCop 등)에서 200~400%의 오버헤드를 기록하여 실무 적용이 어렵습니다. - 이러한 기존 방식들은 대규모 테스트 수트를 빠르게 실행하려는 원래의 목적에 부합하지 않는 성능 결과(기존보다 3~4배 느려짐)를 보였습니다. ## C 확장을 이용한 저수준 인터프리터 이벤트 활용 - 성능 문제를 해결하기 위해 Ruby VM의 내부 동작을 분석하고, C 언어로 직접 커버리지 수집 도구를 개발했습니다. - Ruby 인터프리터 내부에서 사용하는 `rb_thread_add_event_hook` 함수를 활용해 `RUBY_EVENT_LINE` 이벤트를 직접 훅(hook)하는 방식을 취했습니다. - 테스트 시작(start)과 종료(stop) 시점에만 이벤트 훅을 등록 및 해제하며, 실행되는 파일의 경로가 프로젝트 루트 내에 있는지 C 수준에서 빠르게 필터링하여 해시 구조에 저장합니다. - 이 방식은 Ruby 레벨의 추상화 단계를 건너뛰고 VM 이벤트에 직접 접근함으로써, 데이터 수집의 정확성을 유지하면서도 실행 오버헤드를 획기적으로 낮추는 기반이 되었습니다. Ruby 기반의 대규모 프로젝트를 운영 중이라면 매번 전체 테스트를 실행하기보다, 변경 사항에 기반한 지능형 테스트 실행 방식을 도입하여 CI 비용과 시간을 최적화할 것을 권장합니다. 특히 성능에 민감한 환경에서는 표준 API에 의존하기보다 저수준 최적화가 포함된 전문적인 모니터링 도구를 활용하는 것이 효과적입니다.
Dirty Pipe 취약점을 이용한 컨 (새 탭에서 열림)
리눅스 커널에서 발견된 Dirty Pipe 취약점은 권한이 없는 프로세스가 읽기 권한만 가진 파일에 데이터를 쓸 수 있게 허용하며, 이를 통해 컨테이너 환경에서 호스트 시스템의 루트 권한을 탈취할 수 있는 심각한 위협을 초래합니다. 특히 Kubernetes 환경에서 널리 쓰이는 컨테이너 런타임인 runC의 실행 바이너리를 페이지 캐시 수준에서 변조함으로써, 격리된 컨테이너를 탈출하여 호스트 시스템을 완전히 장악하는 시나리오가 가능합니다. 본 글에서는 이 취약점의 기술적 배경과 함께 실제 컨테이너 탈출이 이루어지는 공격 메커니즘을 상세히 설명합니다. **컨테이너 런타임과 runC의 구조적 취약성** - Kubernetes는 containerd나 CRI-O 같은 런타임을 통해 컨테이너를 관리하며, 실제 프로세스 생성은 OCI 규격을 준수하는 하위 레벨 런타임인 runC가 담당합니다. - runC는 컨테이너 내부 프로세스를 실행할 때 자신을 포크(fork)한 뒤 `execve` 시스템 콜을 호출하는데, 이때 `/proc/self/exe` 경로를 통해 호스트에 있는 runC 이진 파일에 대한 파일 서술자(File Descriptor)를 열어두게 됩니다. - 과거 CVE-2019-5736 취약점에 대한 대응으로 runC를 읽기 전용으로 마운트하는 방어책이 도입되었으나, Dirty Pipe는 커널의 페이지 캐시를 직접 수정하므로 이러한 파일 시스템 수준의 권한 제한을 무력화합니다. **Dirty Pipe를 이용한 컨테이너 탈출 과정** - 공격자는 먼저 취약한 웹 애플리케이션 등을 통해 권한이 제한된 일반 컨테이너에 침투한 뒤, 호스트의 runC 바이너리가 실행되기를 대기합니다. - 관리자가 `kubectl exec`와 같은 명령을 수행하여 컨테이너 내부에서 runC가 구동되는 순간, 공격 프로세스는 `/proc/<runC-pid>/exe`를 통해 호스트의 runC 실행 파일에 접근합니다. - Dirty Pipe 공격 프리미티브를 활용하여 페이지 캐시에 로드된 runC 바이너리 내용을 공격자의 악성 ELF 코드로 덮어씁니다. - 이렇게 변조된 runC는 호스트의 루트 권한으로 실행되므로, 공격자는 호스트 시스템에서 임의의 명령(예: 호스트 이름 확인, 루트 권한 쉘 실행 등)을 수행하며 컨테이너 격리를 완전히 무너뜨립니다. **메모리 기반 공격의 비영구적 특성** - Dirty Pipe를 통한 바이너리 변조는 디스크의 실제 파일을 직접 수정하는 것이 아니라 커널의 페이지 캐시 내에서 발생합니다. - 따라서 공격으로 인한 변조는 시스템이 재부팅되거나 커널 캐시가 드롭(drop)되기 전까지만 유지되는 비영구적 특성을 가집니다. - 하지만 단 한 번의 실행만으로도 호스트에 백도어를 설치하거나 권한을 상승시키기에 충분하므로 그 위험성은 매우 높습니다. Dirty Pipe 취약점은 리눅스 커널 수준의 결함이므로 이를 근본적으로 해결하기 위해서는 최신 보안 패치가 적용된 커널로 신속히 업데이트해야 합니다. 또한 컨테이너 환경에서는 최소 권한 원칙을 철저히 준수하고, 런타임 보안 모니터링 도구를 도입하여 `/proc` 파일 시스템에 대한 의심스러운 접근이나 시스템 이진 파일의 비정상적인 동작을 실시간으로 감지하고 차단하는 방어 전략이 필요합니다.
프로덕트 디자이너 (새 탭에서 열림)
훌륭한 제품 디자이너가 되기 위해서는 단순히 결과물을 만드는 것을 넘어, 디자인의 배경과 맥락을 효과적으로 전달하는 '설명가'의 역량이 필요합니다. 이는 단편적인 사실 보도를 넘어 복잡한 사건의 맥락을 짚어주는 '해설 저널리즘(Explanatory Journalism)'과 맥을 같이 하며, 디자이너는 파편화된 정보를 통합하여 이해관계자들에게 올바른 맥락을 제공해야 합니다. 결과적으로 철저한 기록을 통해 구축한 '페이퍼 트레일(Papertrail)'은 디자인 의사결정의 강력한 근거가 되며 팀 전체의 이해도를 높이는 핵심 자산이 됩니다. ## 최신 정보보다 중요한 가치에 집중하기 * 뉴스 피드나 소셜 미디어처럼 실시간으로 쏟아지는 정보(CS 티켓, 회의록, 고객 통화 등)는 '최신성'을 이유로 판단력을 흐리게 만들 수 있습니다. * 디자이너는 이러한 파편화된 피드백을 한데 모으고 출처를 명확히 함으로써, 단순한 최신 요청이 아닌 비즈니스 가치가 높은 '중요한 문제'를 식별해야 합니다. * 다수의 사용자가 공통으로 요청하는 사항을 수치화하고 우선순위를 정하는 과정을 통해, 근거 없는 편향에 빠지지 않고 객관적인 의사결정을 내릴 수 있습니다. ## 맥락의 붕괴(Context Collapse) 방지 * '맥락의 붕괴'는 소셜 미디어처럼 다양한 청중이 하나의 메시지를 각기 다른 맥락으로 받아들일 때 발생하며, 이는 기업 내 협업 과정에서도 빈번하게 나타납니다. * 고객 지원 팀의 티켓, 영업 팀의 요구사항, 연구원의 인터뷰 노트, 경영진의 목표 등 서로 다른 맥락의 정보들을 한곳에 수집하고 통합하는 작업이 선행되어야 합니다. * 디자인 리뷰 시 단순히 결과물만 보여주는 것이 아니라, 수집된 다양한 요구사항들이 최종 솔루션에 어떻게 반영되었는지 각 이해관계자의 언어와 맥락에 맞춰 설명해야 합니다. ## 페이퍼 트레일(Papertrail)을 통한 정보의 확장과 수축 * 디자인 프로세스는 방대한 리서치와 데이터를 수집하는 '확장' 단계와 이를 핵심 요구사항으로 정제하는 '수축' 단계로 나뉩니다. * 인터뷰 기록, 리서치 테마 등을 문서화한 '페이퍼 트레일'을 구축하면 문제 정의가 명확해질 뿐만 아니라, 솔루션의 제약 조건을 설정하는 데 큰 도움이 됩니다. * 풍부한 배경 자료를 스스로 잘 이해하고 있을 때 비로소 타인을 위한 간결하고 효과적인 요약이 가능해지며, 필요시 상세 근거로 바로 연결할 수 있는 신뢰성을 확보하게 됩니다. ## 제품 디자이너와 PM의 역할 협업 * 제품 디자이너는 워크플로우, 인터랙션 디자인, 기능의 세부적인 사용성(Usability)에 집중하여 맥락을 구축해야 합니다. * 이는 제품 관리자(PM)가 수익 모델, 개발 비용, 비즈니스 우선순위 등 사업적 측면에 집중할 수 있도록 돕는 역할을 합니다. * 사용자 경험(UX)의 소유권을 가진 디자이너라면 리서치부터 사후 관리까지 모든 과정의 '맥락'을 관리하는 책임감을 가져야 합니다. 성공적인 디자인을 위해서는 리서치 단계에서부터 인터뷰 대상자의 배경, 핵심 인사이트, 후속 조치 등을 꼼꼼히 기록하는 습관을 들여야 합니다. 이러한 '기록의 흔적'은 본인뿐만 아니라 팀원들에게도 디자인 결정의 타당성을 증명하는 가장 강력한 도구가 될 것입니다.
.NET 지속적 프로 (새 탭에서 열림)
운영 환경의 복잡한 애플리케이션 성능 문제를 해결하기 위해서는 단순한 메트릭 관찰을 넘어 코드 수준의 가시성이 필요합니다. Datadog의 Continuous Profiler가 제공하는 '타임라인 뷰(Timeline View)'는 시간에 따른 CPU 사용량과 스레드 상태 변화를 코드 실행 흐름과 직접 매핑하여 성능 병목의 근본 원인을 직관적으로 제시합니다. 이를 통해 개발자는 운영 환경에 가해지는 부하를 최소화하면서도 간헐적인 지연이나 리소스 효율성 문제를 신속하게 진단하고 최적화할 수 있습니다. ### 프로파일링 가시성의 확장: 플레임 그래프에서 타임라인으로 - 기존의 플레임 그래프(Flame Graph)는 전체 실행 시간 동안의 리소스 점유율을 요약하여 보여주지만, 특정 시점에 발생한 일시적인 성능 저하나 스레드 간의 상호작용을 파악하기에는 한계가 있습니다. - 타임라인 뷰는 시간의 흐름에 따라 스레드별 활동을 시각화하여, 애플리케이션 내에서 코드가 정확히 어느 시점에 실행되고 멈췄는지를 상세히 보여줍니다. - 이 방식은 특히 마이크로서비스 환경에서 발생하는 분산된 요청이나, 주기적으로 반복되는 백그라운드 작업의 성능을 분석할 때 강력한 효과를 발휘합니다. ### 스레드 상태 분석을 통한 지연 시간 진단 - 프로파일러는 각 스레드가 'CPU 실행(Running)', '입출력 대기(I/O Waiting)', '잠금 경합(Lock Contention)' 중 어떤 상태에 있는지 실시간으로 기록합니다. - 특정 요청이 느려질 때, 그것이 복잡한 연산 때문인지(CPU Bound), 아니면 데이터베이스 응답이나 네트워크 호출을 기다리기 때문인지(Wait Time)를 즉각적으로 구분할 수 있습니다. - 가비지 컬렉션(GC) 이벤트가 애플리케이션 스레드를 중단시키는 'Stop-the-world' 구간을 타임라인상에 표시하여, 메모리 관리 효율성이 전체 응답성에 미치는 영향을 분석합니다. ### 운영 환경 최적화와 추적 데이터 결합 - Continuous Profiler는 매우 낮은 오버헤드로 설계되어 운영 환경에서 상시 작동하며, 재현하기 어려운 간헐적인 '스파이크' 현상을 놓치지 않고 포착합니다. - 분산 추적(Tracing) 시스템과 연동되어 특정 요청(Trace ID)과 관련된 프로파일링 데이터를 즉시 연결함으로써, 특정 사용자 요청이 코드의 어느 라인에서 지연되었는지 추적할 수 있습니다. - 코드 변경 전후의 타임라인을 비교하여 성능 최적화 작업이 실제 스레드 효율성이나 응답 시간 개선에 기여했는지를 객관적인 지표로 검증합니다. 운영 중인 서비스에서 원인을 알 수 없는 성능 저하가 발생한다면, 로그 분석에 의존하기보다 Continuous Profiler의 타임라인 뷰를 통해 스레드의 실제 움직임을 관찰하는 것이 좋습니다. 이를 통해 코드 최적화의 우선순위를 명확히 설정하고, 인프라 비용 절감과 사용자 경험 개선이라는 두 가지 목표를 동시에 달성할 수 있습니다.
.NET 지속적 프로파일 (새 탭에서 열림)
지속 프로파일링(Continuous Profiling)의 타임라인 뷰는 운영 환경의 애플리케이션에서 발생하는 미세한 성능 병목과 코드 비효율성을 시각적으로 진단할 수 있게 해줍니다. 기존의 플레임 그래프(Flame Graph)가 전체 실행 시간의 비중을 요약해서 보여준다면, 타임라인 뷰는 시간의 흐름에 따른 스레드별 활동과 자원 사용량을 매핑하여 간헐적인 지연이나 리소스 급증의 원인을 명확히 짚어냅니다. 이를 통해 개발자는 분산 추적(Tracing) 데이터와 개별 코드 실행 흐름을 연결하여 복잡한 런타임 문제를 더 신속하게 해결할 수 있습니다. ### 기존 프로파일링 방식의 한계와 타임라인 뷰의 등장 * **시계열 맥락의 부재**: 플레임 그래프는 특정 기간 내의 전체적인 코드 실행 비중을 보여주지만, 리소스 사용량이 특정 시점에 왜 급증했는지나 실행 순서에 따른 병목은 파악하기 어렵습니다. * **시간 축 기반 분석**: 타임라인 뷰는 X축을 시간으로, Y축을 개별 스레드나 프로세스로 구성하여 코드 실행의 흐름을 직관적으로 보여줍니다. * **데이터의 통합**: 메트릭(CPU/메모리 사용량), 로그, 트레이스를 단일 타임라인에 결합함으로써 특정 성능 저하가 발생한 순간에 어떤 코드가 실행되고 있었는지 즉각적인 확인이 가능합니다. ### CPU 시간과 벽시계 시간(Wall Time)의 차이 분석 * **실제 연산과 대기 시간 구분**: 타임라인 뷰는 스레드가 실제로 CPU를 점유하여 연산하는 시간(CPU Time)과 입출력(I/O)이나 락(Lock) 경합으로 대기하는 시간(Wall Time)을 명확히 구분합니다. * **I/O 병목 식별**: 특정 스레드가 오랜 시간 '대기' 상태로 표시된다면 외부 API 호출이나 데이터베이스 쿼리 응답을 기다리고 있음을 의미하며, 이는 코드 최적화보다 인프라나 네트워크 설정 검토가 필요함을 시사합니다. * **CPU 집약적 작업 포착**: 짧은 순간에 여러 스레드에서 CPU 사용량이 치솟는 구간을 확인하여 복잡한 알고리즘이나 무한 루프와 같은 코드 결함을 찾아낼 수 있습니다. ### 분산 추적(Tracing)과의 긴밀한 연동 * **Span ID 기반 드릴다운**: 특정 요청의 트레이스 정보(Span)를 프로파일러의 타임라인과 연결하여, 해당 요청이 처리되는 동안 각 스레드에서 어떤 함수가 호출되었는지 상세히 추적합니다. * **컨텍스트 스위칭 파악**: 하나의 요청이 여러 스레드를 거쳐 처리될 때 발생하는 컨텍스트 스위칭 비용이나 스레드 풀의 효율성을 시각적으로 검증할 수 있습니다. * **비정상적인 지연 탐지**: 전체 요청 시간은 짧지만 특정 구간에서 비정상적으로 긴 실행 시간이 소요되는 '롱 테일(Long tail)' 문제를 코드 수준에서 진단합니다. ### 가비지 컬렉션(GC) 및 런타임 오버헤드 진단 * **Stop-The-World 감지**: 가비지 컬렉션으로 인해 모든 애플리케이션 스레드가 일시 정지되는 구간을 타임라인에서 명확히 확인하여 메모리 할당 효율성을 평가할 수 있습니다. * **락 경합(Lock Contention) 해소**: 여러 스레드가 동일한 자원에 접근하기 위해 대기하는 구간을 시각화하여, 동기화 로직의 병목을 찾아내고 동시성 제어 구조를 개선할 수 있는 근거를 제공합니다. 운영 환경의 성능 문제를 해결하기 위해서는 단순히 "무엇이 느린가"를 넘어 "언제, 왜 느려졌는가"에 대한 답이 필요합니다. 지속 프로파일러의 타임라인 뷰를 활용하면 높은 수준의 추상화된 메트릭에서 시작해 실제 코드 실행의 세부 디테일까지 단절 없이 탐색할 수 있습니다. 특히 간헐적으로 발생하는 성능 저하를 재현하기 어려운 환경에서, 타임라인 뷰는 실행 시점의 스냅샷을 제공하여 근본 원인 분석(RCA)의 시간을 획기적으로 단축해 줄 것입니다.
2023-03-08 사건: 플랫폼 수준의 영향 깊이 살펴보기 | Datadog (새 탭에서 열림)
2023년 3월 8일 발생한 Datadog의 전사적 서비스 장애는 시스템 관리 데몬인 systemd의 동작 변경과 자동 보안 업데이트 설정이 결합되어 발생한 이례적인 사건입니다. Ubuntu 22.04 환경에서 systemd-networkd가 재시작될 때 기존 IP 라우팅 규칙을 모두 삭제하는 새로운 기본 동작이 활성화되었고, 이것이 전 지역 노드에 동시다발적인 자동 패치로 실행되면서 대규모 네트워크 중단으로 이어졌습니다. 이 사고는 인프라 전반에 걸친 자동화된 변경 관리와 점진적 배포 원칙이 보안 패치라는 예외 상황에서 어떻게 무력화될 수 있는지를 보여줍니다. **systemd-networkd의 IP 규칙 삭제 동작** * 2020년 12월 배포된 systemd v248부터 `systemd-networkd`는 시작 시 자신이 파악하지 못한 모든 IP 규칙(IP rules)을 삭제(flush)하는 동작을 도입했습니다. * 이후 v249에서 `ManageForeignRoutingPolicyRules` 설정을 통해 이 동작을 거부할 수 있는 옵션이 추가되었으나, 기본값은 여전히 기존 규칙을 삭제하는 방식이었습니다. * Datadog이 마이그레이션 중이던 Ubuntu 22.04는 이 위험한 기본 설정이 포함된 systemd v249를 사용하고 있었습니다. **보안 패치와 자동 업데이트의 결합** * 2023년 3월 7일, systemd의 CVE 취약점을 해결하기 위한 보안 패치가 Ubuntu 저장소에 업데이트되었습니다. * Datadog의 서버들은 Ubuntu의 기본 설정인 `unattended-upgrades`를 사용하고 있었으며, 이는 매일 특정 시간(06:00 UTC)에 보안 업데이트를 자동으로 수행하도록 설정되어 있었습니다. * 이 보안 패치가 설치되면서 `systemd-networkd` 서비스가 재시작되었고, 그 즉시 노드의 핵심적인 네트워크 라우팅 규칙들이 모두 삭제되었습니다. **점진적 배포 전략의 무력화** * Datadog은 평소 새로운 OS나 설정을 도입할 때 실험용 클러스터부터 시작해 스테이징, 소규모 리전, 대규모 리전 순으로 수주에 걸쳐 점진적으로 배포하는 엄격한 프로세스를 따릅니다. * 하지만 시스템 레벨의 자동 업데이트(unattended-upgrades)는 이러한 점진적 배포 통제를 우회하여 전 세계 모든 리전의 노드에 거의 동시에 적용되었습니다. * 결과적으로 전체 서버의 90% 이상을 차지하던 Ubuntu 22.04 노드들이 동시다발적으로 네트워크 불능 상태에 빠지게 되었습니다. **실용적인 교훈과 권장사항** 운영 환경에서 OS 배포판을 업그레이드할 때는 시스템 구성 요소(특히 systemd와 같은 핵심 데몬)의 기본 동작 변경 사항을 상세히 검토해야 합니다. 또한, 보안을 위한 자동 업데이트라 할지라도 인프라 전체에 동시에 적용되는 방식은 위험할 수 있으므로, 업데이트 주기를 리전별로 분산하거나 자체적인 패키지 미러를 통해 보안 패치 역시 점진적 배포 파이프라인의 통제하에 두는 것이 권장됩니다.
fetch 실현하기: 범용 (새 탭에서 열림)
Datadog은 대규모 대시보드의 복잡한 데이터 페칭과 렌더링 성능을 최적화하기 위해 기존의 복잡한 휴리스틱 기반 스케줄러를 단순화하고 범용적인 시스템으로 재설계했습니다. 새로운 스케줄러는 쿼리와 렌더링 로직을 분리하고 가시성 중심의 작업 분배 알고리즘을 도입하여 백엔드 부하를 줄였으며, 최신 브라우저 스케줄링 API를 통해 런타임 성능을 극대화했습니다. 결과적으로 코드의 복잡성은 대폭 낮아졌고, API 호출 오류 감소와 함께 전반적인 사용자 경험이 향상되는 성과를 거두었습니다. ### 기존 스케줄러(v1)의 구조적 한계 * 20개 이상의 복잡한 매개변수와 서로 얽힌 휴리스틱으로 구성되어 있어, 개발자가 시스템의 동작을 예측하거나 유지보수하기 매우 어려웠습니다. * 쿼리(데이터 페칭)와 렌더링 스케줄링이 명확히 분리되지 않아, 렌더링 작업이 지연될 때 연관 없는 쿼리까지 함께 지연되는 비효율이 발생했습니다. * 대시보드 환경에만 특화된 로직으로 작성되어 있어, Datadog 내의 다른 제품이나 일반적인 위젯 컴포넌트에서 재사용하기 어려운 구조였습니다. ### 단순하고 효율적인 쿼리 스케줄링 알고리즘 * 화면에 보이는(Visible) 위젯의 쿼리는 즉시 실행하고, 비가시적 위젯의 쿼리는 큐에 쌓아 순차적으로 처리하는 단순한 방식을 채택했습니다. * 비가시적 쿼리는 2000ms의 고정된 시간 윈도우 내에서 최대 10개까지만 실행하도록 제한하여 백엔드 서비스의 부하를 안정화했습니다. * 브라우저가 자체적으로 처리하는 탭 포커스 여부 확인 등의 불필요한 체크 로직을 제거하여 관리 매개변수를 20개에서 6개로 줄였습니다. * 효율적인 작업 분산을 통해 '429(Too many requests)' 에러 발생률을 낮추었으며, 이는 결과적으로 재시도 횟수를 줄여 데이터 로딩 속도를 개선했습니다. ### Browser Scheduling API를 통한 렌더링 제어 * 브라우저의 CPU 및 메모리 자원 상태를 고려하지 못하던 기존 방식의 한계를 극복하기 위해 네이티브 브라우저 스케줄링 API(`postTask`)를 도입했습니다. * 작업을 중요도에 따라 `user-blocking`(사용자 차단), `user-visible`(사용자 가시), `background`(백그라운드) 세 단계로 분류하여 브라우저가 최적의 시점에 실행하도록 위임했습니다. * 중요도가 낮은 렌더링 작업은 브라우저가 유휴 상태일 때 실행되도록 설정하여 메인 스레드의 병목 현상을 방지하고 부드러운 UI 반응성을 확보했습니다. * `TaskController`를 활용해 특정 그룹의 작업 우선순위를 일괄 변경하거나 불필요한 작업을 즉시 중단(abort)할 수 있는 제어 구조를 갖추었습니다. 애플리케이션의 성능 최적화를 고려한다면 복잡한 자체 규칙을 만들기보다 가시성(Visibility)과 같은 핵심 지표에 집중하고, 최신 브라우저가 제공하는 스케줄링 표준 API를 활용하여 시스템 자원을 효율적으로 관리하는 것이 바람직합니다.
Arm64 JIT 컴파일러 (새 탭에서 열림)
Datadog integrations 2025 recap: Observability for AI, security, and hybrid cloud
쿠버네티스 상태 메트 (새 탭에서 열림)
Datadog은 대규모 Kubernetes 환경에서 오픈소스 도구인 kube-state-metrics(KSM)를 운영하며 겪은 확장성 문제를 해결하기 위해 오픈소스 커뮤니티에 직접 기여하여 성능을 대폭 개선했습니다. 기존 KSM은 수천 개의 노드와 수만 개의 포드가 있는 환경에서 지표 수집 시간이 수십 초에 달하고 데이터 용량이 비대해지는 성능 저하 문제를 안고 있었습니다. 이를 해결하기 위해 KSM v2 개발 과정에 참여하여 지표 생성 프로세스를 최적화함으로써 수집 속도를 15배 향상하고 대규모 클러스터에서도 고해상도 데이터를 안정적으로 확보할 수 있게 되었습니다. **KSM의 작동 원리와 기존의 한계** * KSM은 Kubernetes API 서버를 리스닝하며 객체의 상태 지표를 생성하는 서비스로, 인포머(Informer) 패턴을 사용해 클러스터 수준의 메타데이터를 OpenMetrics 형식으로 노출합니다. * Datadog 에이전트는 15초마다 `/metrics` 엔드포인트를 크롤링하여 데이터를 수집하며, 필요에 따라 `label_joins` 설정을 통해 메타데이터를 결합해 지표의 가독성을 높입니다. * 하지만 기존 구조에서는 쿼리 시점에 대량의 데이터가 한꺼번에 덤프되고, 지표 생성 과정에 개입할 수 있는 훅(hook)이 부족하여 성능 확장에 제약이 있었습니다. **대규모 환경에서의 확장성 병목 현상** * 리소스당 지표 생성량을 분석한 결과 노드는 약 9개, 포드는 약 40개의 지표를 생성하며, 수만 개의 포드가 있는 환경에서는 매 수집 주기마다 수백만 개의 지표를 처리해야 합니다. * 이로 인해 네트워크 호출 시간이 수십 초로 늘어나고 데이터 크기가 수십 메가바이트에 달하게 되어, 지표의 정밀도를 낮추거나 수집 주기를 강제로 늦춰야 하는 상황이 발생했습니다. * Datadog은 이를 해결하기 위해 포드, 노드, 기타 리소스별로 KSM 배포를 물리적으로 분리하는 전략을 사용했으나 이는 임시방편에 불과했습니다. **오픈소스 기여를 통한 성능 최적화** * Datadog 팀은 내부적인 수정을 넘어 KSM v2.0.0의 메인 커뮤니티와 협력하여 지표 생성 로직과 빌더(Builder) 구조를 근본적으로 개선했습니다. * 결과적으로 지표 수집 프로세스 소요 시간을 기존 대비 15배 단축하는 성과를 거두었으며, 이는 대규모 인프라 운영의 핵심적인 전환점이 되었습니다. * 이러한 경험은 오픈소스 커뮤니티에 기여하는 것이 개별 기업의 인프라 문제를 해결함과 동시에 기술적 생태계 전체의 성능을 끌어올리는 가장 효과적인 방법임을 시사합니다. **실용적인 결론 및 추천** 대규모 Kubernetes 클러스터를 운영 중이라면 KSM v2 이상의 버전을 채택하여 최적화된 지표 수집 성능을 확보하는 것이 필수적입니다. 또한 단일 KSM 배포에서 성능 저하가 발생할 경우, 본문에서 언급된 것처럼 리소스 유형별(Collectors)로 배포를 분리하여 부하를 분산하는 전략을 검토해 보시기 바랍니다.