Architecture
Grafana Tempo는 Distributor, Ingester, Query Frontend, Querier, Compactor, Metrics Generator(option)를 포함합니다. 각 컴포넌트는 트레이스 수집, 처리, 조회, 그리고 메트릭스 생성 등의 역할을 담당하며, 이들은 전체 trace 데이터의 라이프사이클을 관리합니다.
Distributor
Distributor는 Jaeger, OpenTelemetry, Zipkin을 포함한 여러 형식의 스팬을 허용합니다. traceID를 해싱하고 분산되고 일관된 해시 링을 사용하여 스팬을 Ingester로 라우팅합니다. 최상의 성능을 위해 OTel Proto를 수집하는 것이 권장됩니다.
스팬(span): 시작 시간과 종료 시간을 가지며, 그 사이에 발생하는 이벤트들의 정보(e.g. traceID)를 포함합니다.
Ingester
Ingester는 trace를 block 단위로 배치하고, 블룸 필터와 인덱스를 생성한 후 이를 백엔드로 flush합니다. 백엔드의 블록은 다음과 같은 특정 형식으로 생성됩니다.
<bucketname> / <tenantID> / <blockID> / <meta.json>
/ <index>
/ <data>
/ <bloom_0>
/ <bloom_1>
...
/ <bloom_n>
Query Frontend
Tempo가 수집하는 모든 trace 데이터는 분산 저장소에 저장되며, 이 저장소를 통째로 검색하는 것은 매우 비효율적일 수 있습니다.
Query Frontend는 이런 비효율성을 개선하기 위해 search space를 여러 작은 단위로 나눕니다. 이렇게 나눈 각 "shard"는 병렬로 검색되어 성능이 향상됩니다. Query Frontend는 이러한 sharding 작업을 책임지게 됩니다. Query Frontend는 이 search space를 여러 shard로 나누어서 효율적인 검색을 가능하게 합니다.
Querier는 이러한 sharded 쿼리를 처리하기 위해 streaming gRPC 연결을 통해 Query Frontend에 연결합니다.
Traces은 간단한 HTTP 엔드포인트를 통해 노출됩니다: GET /api/traces/<traceID>
Querier
Querier는 요청된 trace id를 ingester 또는 백엔드 저장소에서 찾는 역할을 담당합니다. 파라미터에 따라, Querier는 ingester를 쿼리하고 백엔드로부터 블룸(bloom)/인덱스를 가져와서 object storage의 블록을 검색합니다.
Querier는 다음 주소에 HTTP 엔드포인트를 노출합니다: GET /querier/api/traces/<traceID>. 하지만 쿼리는 쿼리 프론트엔드로 보내야 하므로 직접 사용되지 않을 것으로 예상합니다.
Compactor
Object Storage에 저장된 데이터를 읽어서 데이터의 효율적인 조회를 위해 재구성하고, 불필요한 데이터를 정리하는 역할을 합니다. 재구성된 데이터는 다시 Object Storage에 저장됩니다.
Metrics generator(option)
수집된 trace로부터 metrics을 추출하고 이를 metrics storage에 저장합니다.
Deployment modes
Monolithic mode
모놀리식 모드는 배포가 가장 간단하지만 components의 양을 늘려 수평적으로 확장할 수 없습니다.
Scaling monolithic mode
이 확장 가능한 모놀리식 모드는 모든 components가 하나의 프로세스 내에서 실행된다는 점에서 모놀리식 모드와 유사합니다. 이 모드는 전체 마이크로서비스 배포의 구성 복잡성 없이도 어느 정도 유연한 확장성을 제공합니다.
Microservices mode
components가 별개의 프로세스에 배포됩니다. 구성 요소별로 확장이 이루어지므로 확장의 유연성이 뛰어나고 장애 도메인을 보다 세분화할 수 있습니다.
https://grafana.com/docs/tempo/latest/operations/architecture/