메인 콘텐츠로 건너뛰기

SigNoz와 ClickHouse 기반 OpenTelemetry Observability 구축 방법

요약

클라우드 인프라 규모가 커지면, 모니터링은 더 이상 "대시보드 몇 개"로 끝나지 않습니다. 수천 개 인스턴스에서 쏟아지는 메트릭과 트레이스를 안정적으로 모으고 저장하고, 또 빠르게 조회할 수 있어야 진짜 오브저버빌리티 플랫폼이라고 부를 수 있죠.

이번 글에서는 SigNoz, ClickHouse, OpenTelemetry(OTEL)를 조합해 대규모 프로덕션 환경에서 실제로 돌아가는 오브저버빌리티 플랫폼을 어떻게 설계했는지 정리해 봅니다. 아키텍처 전체 흐름부터 왜 Prometheus 대신 OTEL을 선택했는지, Kafka·Lambda·ClickHouse 튜닝에서 얻은 실전 팁까지 한 번에 훑어볼 수 있도록 구성했습니다.

SigNoz·ClickHouse·OTEL로 만든 전체 아키텍처 한 눈에 보기

이 플랫폼의 목표는 단순했습니다. "벤더 종속 없이, 다양한 서비스에서 발생하는 메트릭과 트레이스를 한 번에 처리할 수 있는 대규모 텔레메트리 파이프라인을 만들자."

출발점은 애플리케이션과 데이터 시스템입니다. PostgreSQL, Spark, 여러 마이크로서비스 등에서 나오는 메트릭과 트레이스를 OTEL SDK와 Collector가 수집합니다. 이 Collector가 데이터를 배치로 묶고, 샘플링하고, 공통 포맷(OTLP)으로 정리해 다음 단계로 넘깁니다.

AWS 네이티브 메트릭은 CloudWatch → Firehose로 스트리밍한 뒤, 중간에 Lambda를 하나 둬서 태그를 풍성하게 붙입니다. 서비스 이름, 환경, 커스텀 태그 같은 메타데이터를 이 단계에서 붙여두면 나중에 검색·필터링이 훨씬 편해집니다. 이렇게 풍부해진 데이터는 S3에 백업되고, 동시에 로드밸런서를 거쳐 OTEL Collector 레이어로 흘러 들어갑니다.

Collector에서 가공된 모든 텔레메트리(메트릭·트레이스)는 Kafka로 집결합니다. 여기서 Kafka는 사실상 "관측 데이터용 메시지 버퍼" 역할을 합니다. 메트릭과 트레이스는 서로 다른 토픽으로 분리하고, 여러 브로커와 복제(Replication) 설정, 3일 정도의 보존 기간을 둬서 장애나 트래픽 스파이크에도 데이터가 날아가지 않도록 설계했습니다.

Kafka 다음에는 SigNoz Collector가 대기하고 있다가 메시지를 읽어 ClickHouse에 기록합니다. ClickHouse는 시계열 분석에 최적화된 데이터베이스로, 이 아키텍처에서는 메트릭과 트레이스의 메인 저장소 역할을 합니다. 여러 샤드와 리플리카 구성을 통해 장애에도 견디는 구조를 만들고, 90일이 지난 데이터는 S3로 자동 오프로드해 비용을 낮췄습니다.

마지막으로 SigNoz 서버가 이 모든 데이터를 UI로 보여주는 프런트 도어 역할을 합니다. 개발자와 운영자는 여기서 대시보드를 만들고, 트레이스를 따라가며 장애를 디버깅하고, 성능 병목을 찾습니다.

이렇게 수집, 처리, 저장을 느슨하게 분리해 두면 특정 구간에 부하가 몰려도 전체 시스템이 한 번에 무너지지 않고, 각 레이어를 독립적으로 확장하거나 교체할 수 있다는 장점이 있습니다.

Kafka·Lambda·Collector 튜닝에서 건진 실전 노하우

실제 운영 단계에서 가장 크게 체감한 부분은 "디폴트 설정으로는 절대 안 된다"는 점입니다. 특히 Firehose, Lambda, Kafka, OTEL Collector의 설정이 서로 맞물려 있기 때문에, 몇 가지 포인트를 꼭 짚고 가야 합니다.

CloudWatch 메트릭을 Firehose로 보낼 때는 버퍼 크기와 버퍼 시간 설정을 어떻게 하느냐에 따라 Lambda 호출 수와 비용이 크게 달라집니다. 버퍼 크기를 크게 잡으면 Lambda 호출 횟수는 줄어들지만, 태그를 붙인 뒤 메시지 전체 크기가 커져 Firehose에서 "메시지 크기 초과" 오류가 날 수 있습니다. 비용 최적화와 오류 방지를 모두 잡을 수 있는 지점까지 직접 모니터링하며 값을 조정해야 합니다.

Lambda에서 태그를 붙일 때는 AWS ResourceGroupsTaggingAPI를 활용해 스트림에 실시간으로 태그를 추가하는 방식을 썼습니다. 이렇게 하면 나중에 쿼리할 때 "서비스별", "환경별", "오토스케일 그룹별"로 분석하기가 훨씬 쉬워집니다.

OTEL Collector 쪽에서는 sending_queue와 retry_on_failure 설정이 생명줄입니다. Kafka로 내보내는 과정에서 문제가 생기면 Collector는 메모리 큐에 잠시 데이터를 쌓고 재전송을 시도합니다. 큐 사이즈를 너무 작게 잡으면 금방 드롭이 발생하고, 너무 크게 잡으면 인스턴스 메모리를 다 써버려 Collector가 멈춰버릴 수 있습니다. 실제로 큐 길이와 메모리 사용량을 보면서 적절한 타협점을 찾는 과정이 필요합니다.

Kafka 브로커는 가능하면 서로 다른 AZ에 분산해 고가용성을 확보했습니다. OTEL Collector에서 한 번에 보내는 배치가 1MB를 훌쩍 넘기기 때문에 broker의 max_message_bytes도 기본값보다 크게 올려야 했습니다. 이 값이 작으면 Collector는 잘 보내고 있는데 Kafka가 계속 거부하는, 찾기 어려운 병목이 생깁니다.

SigNoz Collector에는 memory_limiter 설정을 강하게 권장합니다. Collector 메모리가 일정 수준 이상 늘어나면 Kafka에서 데이터를 받는 속도를 강제로 늦춰 백프레셔를 걸고, 인스턴스가 OOM으로 죽는 것을 막아줍니다. ClickHouse 노드 역시 인스턴스 타입, 디스크 용량, CPU 사용량을 주기적으로 모니터링하며 실제 트래픽 기준으로 리사이징 전략을 세우는 것이 좋습니다.

Prometheus 대신 OpenTelemetry, 그리고 SigNoz를 선택한 이유

많은 팀이 그렇듯, 초기에는 Prometheus가 기본 선택지였습니다. 그러나 규모가 커지고, 메트릭만이 아니라 트레이스·로그까지 한 번에 다루려 하자 Prometheus 중심의 구조는 한계가 분명해졌습니다.

Prometheus는 "pull 모델"이라 상대적으로 단순한 환경에서는 관리가 쉽지만, 수많은 서비스와 인스턴스가 수시로 생기고 사라지는 환경에서는 스크랩 타깃 관리만으로도 벅차집니다. 게다가 고카디널리티 메트릭이 많아질수록 성능과 비용이 빠르게 치솟습니다.

반면 OTEL은 "push 기반"에 가까운 설계와 유연한 Processor 구조 덕분에, 수집·가공·전송을 원하는 대로 조합할 수 있습니다. Collector 한 번만 바꾸면 데이터를 ClickHouse, Kafka, S3 등 여러 백엔드로 동시에 내보낼 수 있기 때문에 벤더 락인을 피하고, 향후 아키텍처 변경에도 유연하게 대응할 수 있습니다.

SigNoz를 선택한 이유도 이와 맞닿아 있습니다. OTEL과 ClickHouse에 자연스럽게 붙고, 기본적으로 트레이싱 UI, 메트릭 대시보드, 알림까지 제공하니 "바로 써먹을 수 있는" 수준의 기능을 제공합니다. SaaS 솔루션과 달리 오픈소스라서 Exporter를 수정하거나 ClickHouse 스키마를 바꾸고, 쿼리 성능 문제를 직접 들여다볼 수 있다는 것도 큰 장점입니다.

커뮤니티도 활발해서, 실제 프로덕션 튜닝 과정에서 여러 번 도움을 받았다는 점도 실전에서는 빼놓을 수 없는 요소입니다.

오브저버빌리티 스택도 관측해야 진짜 운영이다

흥미로운 부분은, 이 팀이 "오브저버빌리티 스택 자체를 어떻게 모니터링할까?"를 따로 설계했다는 점입니다. OTEL Collector, Kafka, ClickHouse 같은 구성 요소도 결국 하나의 시스템이기 때문에, 여기가 느려지거나 문제가 생기면 전체 관측 데이터가 흔들립니다.

여기서는 Prometheus + OTEL Collector 조합을 사용하되, Prometheus가 각각의 엔드포인트를 직접 긁어가는 구조 대신 Kafka를 사이에 둔 구조를 선택했습니다. 각 호스트마다 OTEL Collector가 떠서 로컬 메트릭(Collector 내부 메트릭, 호스트 메트릭 등)을 Prometheus 형식으로 노출하고, 이걸 Collector가 Kafka로 내보냅니다. 중앙 Collector가 다시 Kafka에서 이 메트릭을 읽어 Prometheus 엔드포인트로 내보내고, Prometheus는 이 하나의 타깃만 스크랩합니다.

이렇게 해두면 Kafka, ClickHouse, Collector 노드를 몇 개 늘리건 줄이건 Prometheus 설정은 건드릴 필요가 없습니다. 토폴로지에 완전히 독립적인 구조가 되기 때문에 스케일 아웃이 쉬워지고, Prometheus 서버가 잠시 다운돼도 메트릭은 Kafka에 쌓였다가 복구되면 다시 흘러 들어옵니다.

결국 "오브저버빌리티의 오브저버빌리티"까지 구축해야 운영자가 안심할 수 있습니다. Collector의 큐 길이, Kafka 지연 시간, ClickHouse 쓰기 지연 같은 메트릭을 꾸준히 모니터링해 두면, 장애가 사용자에게 드러나기 전에 관측 파이프라인에서 이상 신호를 먼저 발견할 수 있습니다.

대규모 트레이싱: 에이전트·Collector·샘플링 전략

트레이스를 제대로 수집하려면 에이전트와 Collector 역할을 명확히 나누고, 레거시 코드에 대한 커스텀 계측도 어느 정도 감수해야 합니다.

애플리케이션 가까이에는 OTEL 에이전트를 사이드카 또는 인프로세스로 붙여 HTTP, gRPC, 지원되는 프레임워크 요청을 자동으로 계측합니다. 에이전트는 가능한 한 가볍게 유지하고, 배치·샘플링·백프레셔 같은 무거운 작업은 Collector에 맡깁니다.

Collector는 에이전트에서 받은 스팬을 모아서 배치로 묶고, 필요에 따라 샘플링하거나 태그를 붙인 뒤 Kafka로 내보냅니다. SigNoz Collector는 Kafka에서 이 스팬을 다시 읽어 ClickHouse에 저장하고, UI에서 이를 조회할 수 있게 합니다.

문제는 자동 계측이 되지 않는 레거시 서비스입니다. 예를 들어 옛 버전의 Vert.x, 구형 JDBC 드라이버, 오래된 Redis 클라이언트 등은 기본 OTEL 계측이 깔끔하게 작동하지 않습니다. 이런 경우에는 얇은 래퍼를 하나 만들어서 쿼리나 커맨드를 수행할 때 OTEL 스팬을 수동으로 열고 닫는 방식으로 계측을 추가했습니다. 번거롭지만, 중요한 레거시 경로의 트레이스를 비워두지 않기 위해 필수적인 작업입니다.

이 팀은 1% 확률 샘플링을 적용했습니다. 모든 요청을 다 트레이스로 저장하면 비용과 저장소 부담이 너무 크기 때문에, 통계적으로 의미 있는 수준의 요청만 선택해 저장하는 전략입니다. 일반적으로 오류가 발생하는 요청은 지연 시간이 길거나 특이 패턴을 보여 샘플링에서도 상대적으로 많이 잡히기 때문에, 1%라도 장애 분석에는 큰 무리가 없었습니다.

오류율이 극단적으로 낮은 서비스라면, 확률 샘플링에 Tail-based sampling(오류가 있는 트레이스는 무조건 저장)을 섞어 쓰는 것도 고려할 만합니다. 이렇게 하면 비용을 관리하면서도 중요한 장애 트레이스를 놓치지 않을 수 있습니다.

수집된 스팬으로부터 지연 시간, 오류 카운트, 요청 시간 분포 같은 "스팬 메트릭"을 ClickHouse에 저장해 두면, 트레이스를 다시 읽어오지 않고도 메트릭 대시보드를 만들 수 있습니다. 이 방식은 대시보드 성능을 높이고, 트레이스 저장 공간을 효율적으로 사용할 수 있게 해 줍니다.

마무리: 우리에게 맞는 오브저버빌리티 플랫폼을 만들려면

지금까지 SigNoz, ClickHouse, OpenTelemetry를 조합해 프로덕션급 오브저버빌리티 플랫폼을 구성한 사례를 큰 그림 위주로 살펴봤습니다.

핵심은 세 가지로 요약할 수 있습니다.

첫째, 수집·처리·저장을 분리한 아키텍처 덕분에 수천 개 인스턴스에서 발생하는 메트릭·트레이스를 안정적으로 받아들이면서도, 부하 급증이나 장애에 유연하게 대응할 수 있습니다.

둘째, Firehose·Lambda·Kafka·Collector·ClickHouse 각각의 설정을 실제 트래픽에 맞게 미세 조정하는 것이 안정성과 비용 최적화의 결정적인 요소였습니다. 디폴트 값 그대로는 절대 프로덕션 규모를 견디기 어렵습니다.

셋째, 관측 파이프라인 자체를 다시 관측하는 구조를 만들고, 트레이스 샘플링·커스텀 계측 전략을 잘 설계함으로써 "끝에서 끝까지 보이는" 관측 경험을 구현했습니다.

만약 여러분 팀이 상용 APM/모니터링 솔루션 비용에 지쳐 있거나, 벤더 락인에서 벗어나고 싶다면, 이 조합은 충분히 검토해 볼 만한 대안입니다. 다만 "설치만 하면 끝"인 제품은 아니기 때문에, 실제 트래픽 패턴과 인프라 특성에 맞춰 지속적으로 튜닝하고 모니터링할 준비가 되어 있어야 합니다.

다음 단계로는 SigNoz 서버 내부 구조, Collector 구성, ClickHouse *MergeTree 스키마 설계 같은 더 깊은 이야기를 다루면 좋습니다. 고카디널리티 메트릭과 대량 스팬을 어떻게 저장하고, 쿼리 지연을 어떻게 줄이는지까지 이해하면, 여러분만의 오브저버빌리티 플랫폼도 한층 더 "프로덕션다운" 모습에 가까워질 것입니다.

출처 및 참고 : Building a Production-Grade Observability Platform with SigNoz, ClickHouse, and OpenTelemetry — Part 1 | by Shivee Gupta | Oct, 2025 | Medium

이 노트는 요약·비평·학습 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.