Apache Kafka

36 개의 포스트

datadog원문

스트리밍 플랫폼으로 대규모 환경에서 흔들림 없는 Kafka 안정성 달성 (새 탭에서 열림)

데이터독(Datadog)은 매일 수백 조 건의 이벤트를 처리하기 위해 수천 개의 토픽과 수백 개의 아파치 카프카(Apache Kafka) 클러스터를 운영하고 있습니다. 기존의 정적인 카프카 설정으로는 대규모 환경에서 발생하는 하드웨어 장애나 트래픽 변동에 유연하게 대응하기 어렵기 때문에, 데이터독은 카프카 인프라를 추상화한 '스트리밍 플랫폼(Streaming Platform)'이라는 제어 계층을 구축했습니다. 이를 통해 애플리케이션의 재설정이나 배포 없이도 실시간으로 트래픽을 리디렉션하고 클러스터를 관리함으로써 시스템의 복원력과 확장성을 극대화했습니다. ### 스트림(Streams)을 통한 파이프라인 복원력 강화 - **논리적 추상화**: 물리적인 카프카 토픽 대신 '스트림'이라는 추상화된 단위를 사용합니다. 스트림은 여러 클러스터와 가용 영역(AZ)에 걸쳐 존재할 수 있으며, 생산자와 소비자는 실제 카프카 토폴로지를 알 필요 없이 안정적인 식별자를 통해 데이터에 접근합니다. - **인프라 디커플링**: 애플리케이션이 특정 카프카 리소스에 종속되지 않기 때문에, 인프라 구성을 실시간으로 변경하거나 트래픽을 새로운 토픽/클러스터로 원활하게 재라우팅할 수 있습니다. ### 실시간 트래픽 페일오버 및 리밸런싱 - **무중단 전환**: 특정 클러스터에 문제가 발생하면 제어 계층이 즉시 새로운 토픽을 생성하고 트래픽을 리디렉션합니다. 생산자는 즉시 새 토픽으로 데이터를 보내고, 소비자는 기존 토픽의 잔량을 처리한 후 새 토픽으로 넘어가는 방식을 통해 데이터 유실 없이 전환이 이루어집니다. - **유연한 운영**: 장애 대응뿐만 아니라 클러스터 폐기, 파티션 수 조정, 부하 분산 등의 작업을 애플리케이션 수정 없이 수 초 내에 수행할 수 있습니다. ### 대규모 환경에 최적화된 Assigner와 소비자 모델 - **자체 코디네이터 개발**: 카프카의 기본 그룹 코디네이터는 세션 타임아웃에 의존하여 반응이 느리다는 단점이 있습니다. 이를 대체하기 위해 개발된 'Assigner'는 클러스터 상태와 CPU 부하 등의 메트릭을 실시간으로 모니터링하여 수 초 내에 워크로드를 재분배합니다. - **병렬 처리 극대화**: 엄격한 순서 보장보다는 '최소 한 번(at-least-once)' 전달 모델을 채택하고 소비 단계에서의 순서 제약을 완화했습니다. 이를 통해 대규모 병렬 처리를 구현하고, 순서 보장이 필요한 경우 이벤트 저장소 하단에서 처리하도록 설계했습니다. ### Head-of-line Blocking 문제 해결 및 고급 커밋 로그 - **스트림 레인(Stream Lanes)**: 서비스 품질(QoS)에 따라 트래픽을 독립적인 '레인'으로 분리합니다. 우선순위가 높은 실시간 데이터가 일시적인 트래픽 급증이나 낮은 우선순위 데이터로 인해 지연되는 것을 방지합니다. - **Dead-letter Queue(DLQ)**: 특정 이벤트(Poison Pill)가 처리를 방해할 경우 이를 별도의 DLQ로 격리하여 파티션 전체가 멈추는 현상을 방지합니다. - **메타데이터 기반 커밋**: 카프카의 단일 포인터 오프셋 커밋 방식에서 벗어나, 커밋 메타데이터 공간을 활용해 파티션 내 여러 오프셋 범위를 동시에 추적합니다. 이를 통해 소비자가 이전 데이터를 재처리하는 동안에도 최신 트래픽을 동시에 처리할 수 있는 유연성을 확보했습니다. 카프카를 대규모로 운영할 때는 인프라를 고정된 자산이 아닌 '교체 가능한 소모품'으로 취급하는 제어 계층이 필수적입니다. 데이터독의 사례처럼 물리적 인프라와 논리적 데이터 흐름을 분리하는 추상화 계층을 구축함으로써, 운영 복잡성을 낮추고 대규모 장애 상황에서도 시스템의 연속성을 보장할 수 있습니다.

datadog1분 읽기큐레이션 요약

스트리밍 플랫폼을 통해

제공된 내용에는 기술 블로그 본문이 포함되어 있지 않고, Datadog의 내비게이션 메뉴와 링크 정보만 있습니다. 따라서 글의 주장, 기술적 세부사항, 섹션별 내용을 정확히 요약할 수 없습니다. 또한 상단 링크는 Gartner Observability Platforms 발표를 가리키지만, 본문 링크는 Kafka 기반 스트리밍 플랫폼의 커스텀 추상화 글을 가리켜 대상 글도 명확하지 않습니다. - 확인되는 정보 - Datadog이 Gartner Magic Quadrant for Observability Platforms에서 Leader로 선정되었다는 홍보 링크 - `streaming-platform-kafka-custom-abstractions` 경로의 Kafka 관련 엔지니어링 블로그 링크 - 인프라 모니터링, APM, 로그, 보안, RUM, CI/CD, AI 등 Datadog 제품 메뉴 - 누락된 정보 - 글 제목과 본문 - 문제 정의 및 설계 배경 - Kafka 커스텀 추상화의 구조와 구현 방식 - 성능, 안정성, 운영상의 trade-off - 결론 및 권장 사항 글 본문이나 정확한 URL을 제공해 주시면 요청하신 형식에 맞춰 한국어로 섹션별 요약을 작성할 수 있습니다.

원문 읽기(새 탭에서 열림)
datadog원문

대규모 시계열 인덱싱 (새 탭에서 열림)

Datadog은 5년 사이 데이터 규모가 30배 이상 급증함에 따라, 기존의 시계열 인덱싱 시스템에서 발생하는 성능 병목과 유지보수 문제를 해결하기 위해 아키텍처를 재설계했습니다. 수조 건의 이벤트를 효율적으로 처리하기 위해 인덱스 서비스를 시계열 데이터 저장소와 분리하였으며, 쿼리 로그를 분석해 인덱스를 자동으로 생성하는 전략을 취했습니다. 이 글은 RocksDB와 SQLite를 기반으로 한 초기 인덱싱 서비스의 구조와 대규모 시계열 데이터를 관리하기 위한 Datadog의 기술적 접근 방식을 다룹니다. ### 메트릭 플랫폼의 계층별 구조 * **수집(Intake) 계층:** 데이터 포인트는 메트릭 이름, 태그(env, host, service 등), 타임스탬프, 수치 값으로 구성됩니다. 수집된 데이터는 메시지 브로커인 Kafka로 전달되어 분석, 인덱싱, 아카이빙 등 다양한 용도로 독립적으로 소비됩니다. * **저장(Storage) 계층:** 데이터 저장소는 두 개의 서비스로 나뉩니다. '시계열 데이터베이스'는 `<시계열_ID, 타임스탬프, 값>` 튜플을 저장하고, '시계열 인덱스' 서비스는 RocksDB를 기반으로 `<시계열_ID, 태그>`를 매핑하여 쿼리 시 필터링과 그룹화를 담당합니다. * **쿼리(Query) 계층:** 분산 쿼리 계층은 인덱스 노드에서 검색된 식별자를 바탕으로 시계열 데이터베이스에서 실제 값을 가져와 병합하며, 필터와 집계 함수(avg 등)를 적용해 최종 결과를 도출합니다. ### 쿼리 로그 분석을 통한 자동 인덱싱 전략 * **풀 스캔 방지:** 특정 메트릭의 전체 데이터를 조회하는 비효율적인 스캔을 피하고자, 태그 기반의 인덱스를 생성하여 쿼리 실행 속도를 최적화했습니다. * **동적 인덱스 생성:** 시스템은 백그라운드 프로세스를 통해 실시간 쿼리 로그를 분석합니다. 쿼리 횟수, 실행 시간, 입력 대비 출력 식별자 비율을 따져 리소스 소모가 큰 '고선택성' 쿼리에 대해 자동으로 인덱스를 생성합니다. * **구체화된 뷰(Materialized Views):** 자주 사용되는 복잡한 쿼리를 미리 계산된 인덱스 형태로 저장함으로써, 반복되는 쿼리 요청을 단순한 키-값 조회로 변환해 CPU와 메모리 리소스를 획기적으로 절감합니다. ### 임베디드 데이터베이스를 활용한 시스템 설계 * **SQLite 기반의 메타데이터 관리:** 인덱스 정의와 쿼리 로그 등 읽기 중심의 데이터는 Go 애플리케이션 내에 임베디드된 SQLite에 저장됩니다. SQL의 유연성 덕분에 CLI를 통한 디버깅과 테이블 관리가 용이합니다. * **RocksDB를 통한 고성능 쓰기 처리:** 매일 발생하는 수조 건의 인덱싱 데이터는 고성능 키-값 저장소인 RocksDB가 처리합니다. 별도의 서버 프로세스 없이 애플리케이션에 직접 통합되어 성능 극대화를 꾀했습니다. * **인덱스 수명 주기 관리:** 일정 기간 쿼리가 발생하지 않아 쓸모없어진 인덱스는 시스템이 자동으로 삭제하여 저장 공간을 효율적으로 관리합니다. 대규모 분산 환경에서 모든 데이터에 대해 미리 인덱스를 생성하는 것은 불가능에 가깝습니다. Datadog의 사례처럼 실제 사용자의 쿼리 패턴을 모니터링하고, 리소스 집약적인 쿼리에 대해 인덱스를 동적으로 생성하는 '쿼리 기반 최적화' 방식은 폭발적인 데이터 성장세 속에서 시스템 가용성을 유지하는 매우 실용적인 전략입니다.

datadog원문

Husky: 대규모 환경에서의 정확히 한 번 데이터 수집과 멀티테넌시 (새 탭에서 열림)

Datadog의 3세대 이벤트 저장소인 Husky는 대규모 멀티테넌트 환경에서 데이터 중복 없는 '정확히 한 번(Exactly-once)'의 인입을 보장하기 위해 데이터 지역성(Locality) 기반의 라우팅 아키텍처를 도입했습니다. 스캔과 집계에 최적화된 Husky의 특성상 고성능 포인트 조회가 어렵다는 점을 극복하기 위해, 결정론적 샤딩을 통해 중복 제거의 범위를 샤드 단위로 한정하여 시스템 복잡도를 낮췄습니다. 이를 통해 테넌트별 데이터 격리 비용을 최소화하고, 가변적인 트래픽 상황에서도 효율적으로 스토리지와 컴퓨팅 자원을 확장할 수 있는 기반을 마련했습니다. ## 샤드 라우터를 통한 데이터 지역성 확보 * **결정론적 매핑**: 업스트림 서비스인 'Shard Router'를 사용하여 이벤트의 ID와 타임스탬프를 기반으로 특정 샤드(파티션 그룹)에 이벤트를 할당합니다. * **샤드 할당 전략**: 각 테넌트에게 고정된 리스트의 샤드를 할당하고, 해당 리스트 내에서 이벤트 ID를 해싱하여 샤드를 선택함으로써 무작위 라우팅을 방지합니다. * **테넌트 격리**: 개별 워커 노드가 노출되는 테넌트와 인덱스의 수를 최소화하여, 시스템 전체의 복잡도를 관리 가능한 수준으로 유지합니다. ## 데이터 지역성 도입의 기술적 이점 * **중복 제거(Deduplication) 효율화**: 동일한 ID를 가진 이벤트는 항상 같은 샤드로 라우팅되므로, 전체 시스템이 아닌 샤드 내부에서만 중복 여부를 확인하면 됩니다. 이벤트 ID 세트가 메모리에 수용 가능한 크기로 유지되어 처리 속도가 비약적으로 향상됩니다. * **스토리지 비용 절감**: Husky는 테넌트별로 데이터를 전용 테이블에 격리하며 파일 단위로 저장합니다. 지역성을 통해 워커당 처리하는 테넌트 수를 제한하면 생성되는 파일 수가 줄어들어, 클라우드 스토리지 비용과 후속 컴팩션(Compaction) 작업의 부하를 동시에 낮출 수 있습니다. * **성능 최적화**: 워커 노드가 처리해야 할 논리적 네임스페이스의 카디널리티(Cardinality)가 낮아짐에 따라 쓰기 성능이 개선되고 리소스 효율성이 높아집니다. ## 동적 환경에서의 라우팅 도전 과제 * **할당 변경 관리**: 특정 테넌트의 트래픽이 갑자기 수십 배 증가하거나 전체 샤드 수가 변경될 때, 기존의 결정론적 규칙을 유지하면서도 유연하게 샤드 배정을 변경해야 합니다. * **분산 노드 간 합의**: 모든 샤드 라우터 노드가 동일한 라우팅 규칙을 공유해야 중복 데이터 유입을 방지할 수 있으며, 이를 위해 노드 간의 일관성 있는 결정 메커니즘이 필수적입니다. * **부하 분산(Load Balancing)**: 모든 샤드에 인입 트래픽이 균등하게 배분되도록 설계하여 특정 워커 노드에 부하가 집중되는 '핫스팟' 현상을 방지해야 합니다. 대규모 분산 시스템에서 데이터 일관성을 유지하며 비용을 최적화하려면, 무상태(Stateless) 라우팅보다는 데이터의 특성에 맞춘 지역성 설계를 우선 고려해야 합니다. 특히 테넌트 수가 많은 SaaS 환경에서는 워커가 처리하는 테넌트의 카디널리티를 물리적으로 제한하는 것이 스토리지 관리 비용을 결정짓는 핵심 요소가 됩니다.

datadog원문

Datadog의 3세대 이벤트 스토어, Husky를 소개합니다 (새 탭에서 열림)

데이터독(Datadog)은 폭발적인 데이터 증가와 다양한 제품군의 요구사항을 충족하기 위해 새로운 이벤트 저장 시스템인 '허스키(Husky)'를 구축했습니다. 기존 시스템은 대규모 멀티테넌트 환경에서 발생하는 성능 간섭과 고비용 구조, 데이터 삭제의 어려움이라는 한계에 봉착했으며, 이를 해결하기 위해 저장소와 클러스터링을 분리하고 효율성을 극대화한 새로운 아키텍처가 필요했습니다. 결과적으로 허스키는 로그, RUM, 보안 데이터 등 다양한 고카디널리티(High-cardinality) 이벤트를 경제적이고 안정적으로 처리할 수 있는 기반이 되었습니다. ### 메트릭과 로그의 기술적 차이 * **메트릭의 효율성:** 메트릭 시스템은 데이터를 `<timeseries_id, timestamp, float64>` 형태의 튜플로 사전 집계하여 저장합니다. '델타-오브-델타(delta-of-delta)' 인코딩을 통해 16바이트 데이터를 2바이트 미만으로 압축할 수 있어 매우 효율적이지만, 태그 카디널리티에 제한이 있습니다. * **로그의 복잡성:** 로그는 이벤트당 킬로바이트(KB) 단위의 크기를 가지며, UUID나 스택 트래적(stack traces)과 같은 고카디널리티 데이터를 포함해야 합니다. 로그 시스템은 모든 문맥(context)을 보존하면서 쿼리 시점에 임의의 차원으로 집계할 수 있는 능력이 필수적입니다. ### 초기 아키텍처의 한계와 클러스터링 개선 * **초기 버전의 문제:** 멀티테넌트 클러스터 내에서 단일 노드의 장애나 특정 테넌트의 과부하가 전체 클러스터의 가용성을 떨어뜨리는 '노이즈 네이버(Noisy Neighbor)' 문제가 빈번했습니다. * **저장소와 클러스터링 분리:** 두 번째 버전에서는 저장 엔진과 클러스터링 로직을 분리했습니다. '샤드 라우터(Shard Router)'가 카프카(Kafka)를 통해 데이터를 샤드 단위로 정리하고, 각 노드는 독립적인 유닛으로 동작하게 하여 장애 전파를 차단했습니다. * **커스텀 쿼리 엔진:** 여러 샤드에 분산된 데이터를 쿼리하고 부분 집계 결과를 병합하는 전용 엔진을 도입하여 신뢰성을 높였습니다. ### 플랫폼 급성장과 새로운 요구사항의 등장 * **제품군의 확장:** 로그뿐만 아니라 네트워크 성능 모니터링(NPM), 실제 사용자 모니터링(RUM), 프로파일러 등 다양한 제품이 출시되면서 저장해야 할 이벤트의 양과 종류가 급증했습니다. * **장기 보관 비용 문제:** 가끔 쿼리하지만 장기간 보관이 필요한 데이터를 기존 아키텍처에서 운영하는 것은 비용 효율성이 낮았습니다. * **데이터 관리 편의성:** GDPR 대응을 위한 특정 데이터의 정밀한 삭제 기능과 테넌트 간의 완전한 자원 격리에 대한 요구가 강해졌습니다. ### 허스키(Husky)의 설계 방향 * **범용 이벤트 저장소:** 로그와 유사한 구조를 가진 모든 유형의 데이터를 수용할 수 있는 유연한 스키마 구조를 지향합니다. * **비용 효율적인 확장:** 스토리지 계층화를 통해 자주 사용되지 않는 데이터는 저렴한 저장소에 보관하면서도 즉시 쿼리가 가능한 구조를 구축했습니다. * **격리 및 제어권 강화:** 특정 테넌트의 트래픽 급증이 다른 테넌트의 쿼리 성능에 영향을 주지 않도록 정교한 할당량(Quota) 관리와 격리 메커니즘을 포함했습니다. 시스템을 설계할 때 단순히 현재의 성능 개선에만 집중하는 것이 아니라, 향후 데이터의 기하급수적인 증가와 다양한 제품 요구사항(비용, 삭제, 격리)을 수용할 수 있는 아키텍처 유연성을 확보하는 것이 중요합니다. 특히 대규모 멀티테넌트 환경에서는 '폭포수 장애'를 방지하기 위해 각 구성 요소를 최대한 독립적으로 격리하는 설계가 필수적입니다.

datadog원문

Kafka-Kit 소개: Kafka 확장을 위한 도구들 (새 탭에서 열림)

데이터독(Datadog)은 매일 수조 개의 데이터 포인트를 처리하기 위해 대규모 카프카(Kafka) 클러스터를 운영하며, 이 과정에서 발생하는 대규모 데이터 이동과 스케일링 문제를 해결하기 위해 **'Kafka-Kit'**을 개발하여 공개했습니다. 이 툴킷은 기존 카프카 표준 도구들의 제약을 넘어 파티션 재배치, 장애 브로커 교체, 저장 용량 기반의 리밸런싱 등을 자동화하고 최적화합니다. 결과적으로 데이터독은 복잡한 카프카 운영 업무를 보다 안정적이고 예측 가능한 방식으로 관리할 수 있게 되었습니다. ### Kafka-Kit의 구성과 목적 * **핵심 도구:** `topicmappr`와 `autothrottle`이라는 두 가지 주요 도구로 구성됩니다. * **주요 기능:** 브로커와 파티션 간의 매핑 관리, 장애 브로커 발생 시 자동 교체, 저장 용량 기반의 파티션 리밸런싱, 복제 속도 자동 제한(Throttling) 기능을 제공합니다. * **개발 배경:** 시스템이 커짐에 따라 데이터 이동 빈도와 크기가 기하급수적으로 늘어나는데, 카프카 기본 도구만으로는 고도의 운영 유연성을 확보하기 어렵다는 점을 해결하기 위해 구축되었습니다. ### 효율적인 데이터 배치를 위한 topicmappr * **결정론적 출력:** 동일한 입력에 대해 항상 동일한 파티션 맵을 생성하여 운영의 예측 가능성을 높입니다. * **최소 이동 브로커 교체:** 브로커 교체 시 전체 맵을 새로 짜는 대신, 문제가 생긴 브로커의 빈자리만 채우는 방식으로 데이터 이동을 최소화합니다. 기본적으로 ISR(In-Sync Replicas) 상태가 정상인 파티션은 건드리지 않습니다. * **랙(Rack) 및 저장 공간 인지:** 카프카의 `broker.rack` 태그와 주키퍼(ZooKeeper) 메타데이터를 활용하여 물리적 위치와 저장 용량(Bin-packing)을 고려한 안전한 배치를 수행합니다. * **복제 계수(RF) 조정:** 운영 중인 토픽의 복제 계수를 실시간으로 쉽고 빠르게 변경할 수 있습니다. * **실행 요약 제공:** 파티션 맵을 실제로 적용하기 전, 브로커 분포 변화와 예상 결과를 요약하여 사용자에게 미리 보여줍니다. ### 파티션 배치 전략: Count 전략 * **리더십 최적화:** 브로커 간의 리더 파티션 분포를 극대화하고, 각 브로커가 보유하는 파티션 수를 균등하게 유지합니다. * **균등한 데이터 흐름:** 모든 파티션에서 일정한 데이터 흐름이 예상될 때 유용하며, 메트릭 데이터 없이도 빠르게 맵을 생성할 수 있습니다. * **브로커 관계 다양화:** 단순히 파티션 수만 맞추는 것이 아니라, 특정 브로커들끼리만 복제본을 공유하는 '클러스터링' 현상을 방지하기 위해 브로커 간의 복제 관계를 최대한 분산시킵니다. ### 기술적 구현 및 운영 이점 * `topicmappr`는 Go 언어로 작성되어 실행 파일 형태로 어디서든 쉽게 구동할 수 있으며, 주키퍼 클러스터와 통신하여 실시간 메타데이터를 확인합니다. * 지정된 모든 브로커의 활성 상태를 검증하고, 파티션 맵을 생성하기에 충분한 브로커가 있는지 사전에 체크하여 운영 실수를 방지합니다. * 표준 `kafka-reassign-partitions.sh`와 호환되는 입력 파일을 생성하므로 기존 워크플로우에 쉽게 통합할 수 있습니다. 대규모 카프카 환경에서 데이터 불균형이나 브로커 장애 대응으로 고민하고 있다면, 단순한 파티션 분산을 넘어 저장 용량과 물리적 인프라 구조를 모두 고려하는 Kafka-Kit 도입을 검토해 볼 가치가 있습니다.