여기어때, OpenTelemetry와 ClickHouse로 APM 스캐터 차트 구축
핵심 내용
여기어때가 OpenTelemetry와 ClickHouse를 연동해 개별 요청 분포를 시각화하는 APM 스캐터 차트를 구축했다.
자세히 보기
여기어때는 기존 집계 지표가 개별 요청의 분포 정보를 소실하는 문제를 해결하기 위해 OpenTelemetry와 ClickHouse를 활용해 APM 스캐터 차트를 구축했다. 기존 OTel/Grafana 파이프라인에서 경로를 분기해 전체 트래픽의 개별 span 데이터를 ClickHouse에 저장하고, Grafana 커스텀 패널로 시각화한다.
스캐터 차트 설계와 데이터 저장 전략
스캐터 차트의 점 단위는 개별 span이며, X축은 시작 시각 대신 종료 시각(timestamp + duration)을 사용해 현재 시스템 지연을 파악할 수 있도록 설계했다. 진입점(span)은 기본 표시하고 하위 호출은 숨기는 방식으로 가독성을 높였다.
ClickHouse는 컬럼 지향 구조로 조회 대상 컬럼만 읽어 디스크 I/O 효율을 높이고, 높은 압축률을 제공한다. 로컬 실측 기준 ZSTD 적용 시 원본 대비 약 1/10(90% 감소)의 저장 공간을 차지한다. MergeTree 엔진의 특성상 빈번한 소량 INSERT는 성능 저하를 유발하므로 대량 배치 처리를 선호하며, ORDER BY를 통해 물리 정렬 및 인덱스를 정의한다.
OpenTelemetry Collector 연동 및 필터링
공식 ClickHouse Exporter(beta)를 사용해 데이터를 전송하며, 기존 트레이싱 경로와 스캐터 차트 경로를 분리해 샘플링으로 인한 트래픽량 왜곡을 방지한다. 신규 경로에서는 파트 폭증을 막기 위해 batch timeout을 2s, send_batch_size를 2048으로 설정했다.
필터링은 사용자 관점의 처리 단위와 응답시간 의미를 기준으로 한다. INTERNAL span 중 스케줄러를 제외하고, 비-HTTP CLIENT span 및 헬스체크는 제외한다. OTel Collector의 filter processor를 활용해 DROP 조건을 설정하고, error_mode: ignore로 파이프라인 중단을 방지한다.
스키마 최적화와 인덱스 구성
원본 데이터(raw, TTL 1일)와 조회용 데이터(transactions, TTL 7일)를 분리하고, Materialized View를 통해 Map 접근 및 타입 변환을 사전 처리한다. LowCardinality(String)을 적용해 고유값이 적은 컬럼의 저장 효율을 높이고, FixedString(32)을 trace_id에 적용했다.
ORDER BY는 (service_namespace, service_name, toUnixTimestamp(timestamp), trace_id)로 구성해 프리픽스 필터링을 최적화한다. 정렬 키에 포함되지 않은 컬럼 검색을 위해 bloom_filter, minmax 등의 Skip Index를 사용하며, 전체 시간 범위 조회 시 ts_end의 minmax skip index로 granule pruning을 수행해 저장 및 INSERT 비용을 절감한다.
이 한국어 요약은 AI가 자동으로 만들었습니다. 원문의 주장과 맥락은 원문에서 확인해 주세요. 저작권은 원저작자에게 있습니다.