Grafana로 모니터링 서버 구축하기에서 이번엔 LGTM 중 T인 Tempo 에 대해 알아보자
이전 글이 궁금하다면?
2025.01.19 - [개발 아카이브] - Grafana LGTM 톺아보기 (1) - Loki 란?
2025.02.02 - [개발 아카이브] - Grafana LGTM 톺아보기 (2) - Alloy 란?
Tempo 또한 그라파나에서 제공하는 오픈소스이며, 사용하기 쉬운 대규모 분산 추적 시스템이다.
Loki, Grafana와 결합돼 유의미한 데이터를 만들어나갈 수 있다.
https://github.com/grafana/tempo/tree/main
GitHub - grafana/tempo: Grafana Tempo is a high volume, minimal dependency distributed tracing backend.
Grafana Tempo is a high volume, minimal dependency distributed tracing backend. - grafana/tempo
github.com
Tempo가 수집하는 데이터 = Trace
Tempo는 분산된 trace를 수집한다.
Trace란?
- 분산 되어있는 마이크로 서비스 시스템에서 발생하는 요청이나 트랜잭션이 여러 구성요소를 거치면서 이루어지는 일련의 과정이나 경로를 기록한 것을 말한다.
예를 들어, 유저가 회원가입을 한다고 치면,
1. 유저의 토큰을 저장하고
2. 유저의 정보를 확인하고
3. 유저의 정보를 저장한다.
이 모든 1~3번의 과정을 한번에 볼 수 있는 것이다.
Trace를 통해 하나의 API 요청이 있으면 시스템 내부에서 어떻게 처리되는지 어디가 지연되는지, 문제가 발생한 곳은 어디인지 파악하는데 도움이된다.
Trace를 설정하면 모든 이벤트에 고유한 trace id 가 부여된다. 이 trace id 가 적용되면서 이벤트의 소요시간을 추적할 수 있다.
기존에 Tempo 말고 ElasticSearch 나 Cassandra 같은 데이터베이스가 필요했으며 이는 관리하기 어려웠고 확장에 어려웠다.
인덱싱 및 추적 저장에 비용이 많이 들었다.
Tempo는 이를 해결하기 위하여 대규모 규모를 위해 구축되었다.
종속된 저장소가 아니라 s3나, GCS같이 별도의 객체 저장소를 사용할 수 있게 해 효율적이고 확장성이 뛰어나다.
오픈소스 도구와의 강력한 통합 오픈 소스 추적 프로토콜과 호환 됨.
Tempo 동작 방식
Alloy같은 수집기에서 데이터를 수집하여 Tempo로 전송한다.
Tempo는 s3와 종속적이지 않은 별도의 객체 저장소와 연동 돼, 효율적이고 확장 가능하게 데이터를 추적한다
그라파나에 tempo 데이터를 보내 시각화한다.
자세한 아키텍처는 다음과 같다.
- Distributor
distributors는 Jaeger, OpenTelemetry, Zipkin 같은 데이터 수집기에서 보내준 데이터를 수집한다.우리는 alloy가 보낼것이다)
이 데이터들에 traceID를 통해, 효율적으로 분산되게한 다음, ingestor에게 전달한다.
( It routes spans to ingesters by hashing the traceID ) 이게 원문인데, 어떻게 해야 좋게 해석해야할지 몰라서 원문을 쓴다.
이때 traceId 를 부여하는 방식은, Consistent Hash Ring 방식을 사용한다고 한다.
Consistent Hash Ring?
오..예전에 봤던 알고리즘인데 여기서 나오네 쉽게 설명하면 해시 기반으로 분산저장을 하려면 만약, 3개로 나눌거면 %3, 5개로 하면 %5 로 mod 계산 하는게 가장 쉽겠지만 hash(key) % N 에서 몇개로 나뉠지 N개가 유동적이라면 곤란해진다.
해시 값을 원형 링(0~2³²)으로 배치하고, 서버도 해시 값으로 링에 배치.
• 각 키는 해시 값 기준으로 링에서 시계 방향으로 가장 가까운 서버에 저장.
• 서버 추가/삭제 시 영향을 받는 데이터가 일부에 국한됨
예를 들어 해시 링을 0~100 사이 숫자로 구성.
1. 서버 A(10), 서버 B(40), 서버 C(80)에 배치.
2. 키(데이터)를 해시링에서 가장 가까운 서버에 배치.
• key = 25 → 서버 B(40)
• key = 90 → 서버 A(10) (순환 구조)
그러면,서버 B(40) 제거 시:
• 기존 B(40)이 처리하던 키들이 서버 C(80)로 이동.
• 다른 서버(A, C)는 영향을 받지 않음.
그래서, 아래에서 설명할 각 요소마다 해시 링을 별도로 생성해서 트래픽을 균등하게 분배한다는것 같다.
- Ingestor
Ingestor는 trace를 blocks 로 배치 단위로 필터링이나 인덱싱을 하여 각 저장소로 보내 저장한다.
저장소에서는 다음과 같이 인덱싱돼 저장될 것이다.
<bucketname> / <tenantID> / <blockID> / <meta.json>
/ <index>
/ <data>
/ <bloom_0>
/ <bloom_1>
...
/ <bloom_n>
- Query Frontend
Trace를 검색하는데 작동한다.
- 사용자가 HTTP 요청을 보냄 → GET /api/traces/<traceID>
- Query Frontend는 검색할 blockID 공간을 여러 shard로 나누고 요청을 큐(queue)에 저장.
- Querier들이 gRPC 스트리밍 방식으로 Query Frontend에 연결하여 쿼리 처리.
- 처리된 결과를 Query Frontend가 받아서 클라이언트에게 반환.
- Querier
Trace를 검색하는데 작동한다.
- Query Frontend가 sharding한 요청을 Querier에게 전달.
- Querier는 요청된 Trace ID를 Ingesters 또는 Backend Storage에서 검색.
- Ingester에서는 최신 데이터를 찾는다.
- 검색 결과를 Query Frontend에 반환하여 최종적으로 클라이언트에 응답.
- Compactor
Backend Storage(객체 저장소)에 저장된 블록(Block)들을 최적화하는 역할을 수행.
• 여러 개의 작은 블록을 하나의 큰 블록으로 병합(Compaction)하여 저장 공간을 절약한다.
• 데이터가 조각나서 검색 성능이 저하되는 문제를 방지.
- Metrics Generator(Optional)
수집된 트레이스 데이터를 기반으로 메트릭을 생성할 수 있다.
Distributor가 들어오는 스팬(Span)을 Ingester와 Metrics-generator로 동시에 전달한다.
Metrics-generator는 이를 분석하고 생성된 메트릭을 메트릭 저장소(Prometheus, Mimir 등)에 저장할 수 있다.
• TraceQL 쿼리를 기반으로 특정 트랜잭션, 레이턴시(응답 속도) 등의 성능 지표를 생성
모니터링 서버에 Tempo 적용하기
tempo를 적용하기 위해서는 config 파일로 정의해서 각 요소들에 튜닝을 하면서 적용하면된다.
자세한 내용은 공식문서에 잘 적혀있다
연동한 이후에는 그라파나 대시보드에서 TraceQL 라는 언어로 쿼리를 검색하면 된다.
다음과 같이 조건을 걸면, http status_code 가 200~299인 span 만 필터링이 될것이다.
{ span.http.status_code >= 200 && span.http.status_code < 300 }
결국엔 Tempo의 각 요소를 어떻게 설정하는지에 따라, Tempo의 성능과 직결될것 같다.
'개발 아카이브' 카테고리의 다른 글
Grafana LGTM 톺아보기 (4) - Mimir 란? (3) | 2025.03.02 |
---|---|
Grafana LGTM 톺아보기 (2) - Alloy 란? (7) | 2025.02.02 |
Grafana LGTM 톺아보기 (1) - Loki 란? (5) | 2025.01.19 |
당근 채팅 시스템은 어떻게 만들까? (5) | 2024.12.08 |
slack 파일 업로드, completeUploadExternal(),getUploadURLExternal() 사용법 (3) | 2024.11.19 |