stream-processing

3 개의 포스트

datadog4분 읽기큐레이션 요약

대규모 환경에서 데이터 완전성을 측정하는 방법

고객의 대시보드·알림·AI 에이전트가 올바르게 작동하려면 Datadog에 유입된 모든 텔레메트리 데이터가 완전하게 전달되어야 한다. Datadog은 수백 개의 분산 파이프라인과 고객별 경로를 실시간으로 추적하기 위해 파이프라인을 세그먼트로 나누고, 각 payload의 생성과 확인(acknowledgment)을 비교한다. 이 방식은 중복·순서 뒤바뀜·지연 데이터가 존재하는 환경에서도 세그먼트별 문제 위치와 전체 파이프라인의 완전성을 계산하도록 설계되었다. ## Datadog에서 데이터 완전성의 의미 - 완전한 데이터란 Datadog에 들어온 모든 payload가 고객에게 제공되는 상태다. - 대상 payload에는 다음과 같은 텔레메트리 데이터가 포함된다. - 메트릭 데이터 포인트 - 로그 - 트레이스 - 기타 수집 데이터 - 완전성은 전역 단위가 아니라 **고객별로** 판단해야 한다. - 고객마다 파티셔닝, 격리 전략, 트래픽 패턴이 다르다. - 따라서 동일한 리전에서도 데이터가 통과하는 경로가 매우 다양하다. - 시스템은 데이터가 누락되었는지뿐 아니라 다음도 즉시 설명해야 한다. - 어느 구간에서 문제가 발생했는가 - 어떤 서비스가 비정상인가 - 문제가 고객에게 영향을 주었는가 - 진단 결과는 운영자가 수 초 안에 대응하거나 자동화된 시스템이 조치하는 데 사용된다. ## 워터마크 방식의 한계 - 초기에는 Flink 같은 스트리밍 시스템의 워터마크 방식을 고려했다. - 데이터가 일정 시간 안에 도착한다고 가정하고 워터마크를 전진시킨다. - 특정 임계점을 넘으면 해당 시점까지 데이터가 완전하다고 판단한다. - 그러나 Datadog 환경에서는 고객이 임의로 지연된 데이터를 보낼 수 있다. - 또한 다음과 같은 특수 상황이 워터마크를 신뢰하기 어렵게 만든다. - 파이프라인 내부의 루프 - 트래픽 재생 - 예측하기 어려운 데이터 지연 - 따라서 데이터 도착 시점만으로 전체 파이프라인의 완전성을 판단하는 방식은 필요한 보장을 제공하지 못했다. ## 파이프라인을 세그먼트로 분할 - Datadog은 전체 파이프라인을 여러 개의 작은 세그먼트로 나누어 추적한다. - 예를 들어 다음과 같은 흐름이 있을 수 있다. - intake → Kafka → processing → Kafka → router - 각 서비스 내부와 서비스 간 연결을 별도의 세그먼트로 정의한다. - `intake-in → intake-out` - `intake-out → processing-in` - 각 세그먼트에서 다음을 독립적으로 측정한다. - 세그먼트에 들어온 payload 수 - 세그먼트에서 나간 payload 수 - 이 구조의 장점은 다음과 같다. - 누락이 발생한 위치를 구체적으로 찾을 수 있다. - 개별 세그먼트 결과를 합쳐 end-to-end 완전성을 계산할 수 있다. - 파이프라인에 분기 경로가 추가되거나 제거되어도 전체 시스템을 재정의할 필요가 적다. ## 생성 이벤트와 확인 이벤트로 payload 추적 - payload가 세그먼트에 들어오면 `create` 이벤트를 기록한다. - payload가 세그먼트를 빠져나오면 동일한 식별자에 대한 `acknowledgment` 이벤트를 기록한다. - 두 이벤트의 수를 비교해 세그먼트에서 데이터가 유실되었는지 판단한다. - 재시도와 중복 처리를 위해 모든 payload에 고유 식별자를 부여한다. ### 시간 버킷을 이용한 멱등성 - 분산 시스템에서는 이벤트가 중복되거나 순서가 뒤바뀐 채 도착할 수 있다. - 이를 처리하기 위해 완전성을 payload가 Datadog에 처음 들어온 시점의 **시간 버킷** 단위로 계산한다. - 고객 시스템의 시계가 아니라 Datadog이 관리하는 타임스탬프를 사용한다. - 각 버킷에서 payload의 세그먼트별 상태를 관리한다. - 생성됨 - 확인됨 - 생성 이벤트보다 확인 이벤트가 먼저 도착함 - 같은 버킷에서 동일한 식별자의 `create` 또는 `acknowledgment`가 반복되면 기존 상태를 확인하고 중복 이벤트를 무시한다. - 이 방식은 별도의 분산 조정 없이도 카운트를 멱등적으로 유지한다. ## 세그먼트 비율로 전체 완전성 계산 - 각 세그먼트의 완전성은 다음 비율로 정의된다. `세그먼트 완전성 = 세그먼트를 빠져나간 payload 수 ÷ 세그먼트에 들어온 payload 수` - 순차적으로 연결된 파이프라인에서는 각 세그먼트의 완전성 비율을 곱한다. - 예를 들어 두 세그먼트의 완전성이 각각 98%, 96%라면 전체 완전성은 다음과 같다. `98% × 96% = 94%` ### 병렬 분기 처리 - 병렬 분기를 단순히 하나의 파이프라인으로 취급하면 문제가 생긴다. - 예를 들어 APM 트레이스가 다음 두 서비스로 동시에 전달될 수 있다. - 오류율·요청 수를 계산하는 서비스 - 지연 시간 분포를 계산하는 서비스 - 한 분기가 늦게 처리되면 다른 분기에서 이미 사용 가능한 데이터까지 전체적으로 불완전한 것처럼 보일 수 있다. - Datadog은 병렬 분기를 **데이터 처리량에 비례한 가중 평균**으로 결합한다. - 각 분기의 기여도를 해당 분기가 처리하는 payload 양에 따라 산정한다. - 데이터가 많은 분기는 전체 결과에 더 큰 영향을 준다. - 예시에서는 한 분기가 98%와 96%의 두 세그먼트를 거쳐 94% 완전성을 보이고, 다른 분기는 100%를 처리한다. - 이후 각 분기의 처리량을 기준으로 가중치를 적용해 전체 파이프라인 완전성을 계산한다. ## 실용적인 결론 대규모 분산 수집 시스템에서는 전체 파이프라인을 한 번에 관찰하기보다, payload의 이동을 세그먼트별로 계측하는 편이 문제 위치와 고객 영향을 더 정확히 파악할 수 있다. 특히 고유 식별자, 시간 버킷, 멱등적인 상태 추적을 함께 사용하면 재시도와 지연 데이터가 많은 환경에서도 실시간 완전성 검증이 가능하다.

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

Apache Flink + RocksDB 튜닝으로 광고 Frequency Capping 실시간 집계를 일주일까지 확장하기 (새 탭에서 열림)

토스 데이터 서비스 플랫폼 팀은 광고 노출 집계의 정확성을 높이고 서빙 효율을 개선하기 위해, 기존 Airflow 배치와 Flink 스트리밍이 혼재된 시스템을 전면 Flink 기반의 실시간 슬라이딩 집계 시스템으로 전환했습니다. 1분부터 7일까지의 광범위한 집계 구간을 단일 Redis 조회로 제공하기 위해 집계 특성별로 Flink 앱을 분리하고, RocksDB 및 런타임 설정을 최적화하여 비즈니스 오차를 최소화했습니다. 이 과정에서 대규모 상태(State) 관리와 초기 데이터 적재의 정합성 문제를 해결하며 운영 신뢰성을 확보했습니다. ### 광고 노출 제어(Frequency Capping)의 중요성 * 광고주 예산 낭비를 막고 노출 기회 손실을 방지하기 위해 사용자별 광고 노출 횟수를 정확하게 카운트하고 제어하는 메커니즘입니다. * 광고 상품에 따라 '하루 3회', '7일간 1회' 등 집계 구간이 다양하므로, 1분부터 7일까지의 모든 구간에 대해 이벤트 단위의 정밀한 슬라이딩 윈도우 집계가 필요합니다. ### 기존 시스템의 한계와 개선 동기 * 기존에는 Airflow를 이용해 당일(Head), 과거(Mid), 경계 보정(Tail)의 3단계로 나누어 처리하는 배치 구조를 사용했으나, 유지보수해야 할 DAG가 너무 많고 구조가 복잡했습니다. * 서빙 시점에 구간별로 Redis를 최대 4회 조회해야 하는 구조적 번거로움이 있었으며, 실시간으로 변하는 슬라이딩 윈도우를 정밀하게 구현하는 데 한계가 있었습니다. ### 병목 패턴에 따른 앱 분리 및 아키텍처 * 집계 구간별 병목 현상이 다르다는 점에 착안하여 시스템을 **Minutes**(1~30분), **Hours**(최대 12시간), **Days**(최대 7일)의 3개 앱으로 분리했습니다. * **Minutes**: 빈번한 만료 처리로 인한 Write Stall이 주요 병목이며, RocksDB Write 경로 튜닝이 핵심입니다. * **Hours**: 대량의 광고 ID 누적으로 인한 Filter Block Cache Miss와 CPU 포화가 발생하여 Managed Memory 증설이 필요합니다. * **Days**: Savepoint가 230GB에 달하는 대규모 상태가 병목이며, Checkpoint I/O 문제를 해결하기 위해 Changelog State Backend를 활용합니다. * Flink State를 '단일 진실 공급원(SSOT)'으로 삼아, 장애 발생 시에도 Redis를 State로부터 언제든 다시 구성할 수 있도록 설계했습니다. ### 초기 적재와 전환 정합성 확보 * 7일치의 과거 데이터를 채우는 과정에서 '백필(카운트만 수행)'과 '캐치업(카운트와 만료 타이머 함께 등록)' 파이프라인을 분리하는 2단계 구조를 설계했습니다. * 백필 도중 만료 타이머가 미리 발화하여 집계가 틀어지는 문제를 방지하기 위해, 백필 완료 후 특정 시점부터만 Redis에 쓰기가 수행되도록 제어했습니다. * `withIdleness` 설정을 통해 특정 파티션의 지연이 전체 Watermark 진행을 막지 않도록 하고, `timerState`의 TTL을 윈도우보다 길게 설정해 지연 상황에서도 감소 로직이 누락되지 않도록 보장했습니다. ### RocksDB와 런타임 최적화 * **Minutes 앱**: Write Buffer Manager(WBM) 압박을 완화하여 RocksDB가 쓰기를 멈추는 Write Stall 현상을 방지했습니다. * **Hours 앱**: Bloom Filter 및 메모리 설정을 통해 캐시 미스를 줄여 CPU 효율을 높였습니다. * **Days 앱**: 거대한 SST 파일로 인한 체크포인트 부하를 줄이기 위해 레벨 최적화와 Changelog 메커니즘을 적용했습니다. 대규모 데이터를 다루는 실시간 집계 시스템에서는 모든 구간을 하나의 설정으로 처리하기보다, 데이터의 규모와 병목 지점에 따라 앱을 분리하고 각기 다른 RocksDB 튜닝 전략을 적용하는 것이 운영 안정성 측면에서 효과적입니다. 또한, 상태(State)를 시스템의 최상위 데이터 원천으로 관리하는 원칙을 지킬 때 장애 복구와 데이터 정합성 유지가 훨씬 용이해집니다.

netflix원문

넷플릭스가 실시간 분산 그래프를 구축한 방법과 이유: 1부 — 인터넷 규모의 데이터 스트림 수집 및 처리 (새 탭에서 열림)

넷플릭스는 비디오 스트리밍을 넘어 광고, 라이브 이벤트, 모바일 게임으로 비즈니스를 확장하면서 발생하는 데이터 파편화 문제를 해결하기 위해 '실시간 분산 그래프(RDG)'를 구축했습니다. 기존 마이크로서비스 아키텍처에서 발생하는 데이터 고립을 극복하고, 다양한 서비스 접점에서 발생하는 사용자 활동을 실시간으로 연결하여 개인화된 경험을 제공하는 것이 핵심 목표입니다. 이를 통해 복잡한 데이터 조인 없이도 수억 개의 노드와 엣지 사이의 관계를 즉각적으로 파악할 수 있는 기술적 기반을 마련했습니다. **데이터 파편화와 비즈니스 환경의 변화** * 스트리밍, 게임, 라이브 스포츠 등 서비스 영역이 넓어지면서 사용자가 여러 기기와 도메인에서 수행하는 활동을 하나의 맥락으로 통합해야 할 필요성이 커짐. * 넷플릭스의 강점인 마이크로서비스 아키텍처(MSA)는 서비스 독립성에는 유리하지만, 데이터가 각 서비스에 고립(Silo)되어 있어 통합적인 데이터 과학 및 엔지니어링 작업에 큰 비용이 발생함. * 기존 데이터 웨어하우스 방식은 데이터가 서로 다른 테이블에 저장되고 처리 주기가 제각각이라, 실시간으로 연관 관계를 분석하는 데 한계가 있음. **그래프 모델 도입의 기술적 이점** * **관계 중심 쿼리:** 테이블 기반 모델에서 필요한 비용 중심적인 조인(Join)이나 수동적인 비정규화 없이도 노드와 엣지 사이를 빠르게 탐색(Hop)할 수 있음. * **유연한 확장성:** 새로운 엔티티나 관계 유형이 추가될 때 대대적인 스키마 변경이나 아키텍처 재설계 없이도 신속하게 데이터 모델을 확장할 수 있음. * **패턴 및 이상 탐지:** 숨겨진 관계, 순환(Cycle) 구조, 그룹화 등을 식별하는 작업을 기존의 포인트 조회 방식보다 훨씬 효율적으로 수행함. **실시간 데이터 수집 및 처리 파이프라인 (RDG 레이어 1)** * 전체 시스템은 수집 및 처리, 저장, 서빙의 3개 레이어로 구성되며, 첫 번째 단계인 수집 레이어는 이기종 업스트림 소스로부터 이벤트를 받아 그래프 데이터를 생성함. * DB의 변경 사항을 추적하는 CDC(Change Data Capture)와 애플리케이션의 실시간 로그 이벤트를 주요 소스로 활용하여 데이터 소외 현상을 방지함. * 수집된 원시 데이터는 스트리밍 처리 엔진을 통해 그래프 스키마에 맞는 노드와 엣지 형태로 변환되며, 대규모 트래픽 환경에서도 실시간성을 유지하도록 설계됨. 복잡하게 얽힌 현대의 서비스 환경에서 데이터 간의 관계를 실시간으로 규명하는 것은 사용자 경험 고도화의 핵심입니다. 넷플릭스의 RDG 사례처럼 파편화된 마이크로서비스의 데이터를 그래프 형태로 통합하는 접근 방식은, 실시간 통찰력이 필요한 대규모 분산 시스템 설계 시 강력한 해결책이 될 수 있습니다.