Overview

Opis

Źródło: https://grafana.com/oss/tempo/

Tempo to wysokowydajny, ekonomiczny rozproszony backend do tracingu. Jest głęboko zintegrowany z Grafaną, Prometheusem, Loki i Mimirem. Tempo wymaga jedynie object storage do działania, co czyni go niezwykle tanim i prostym w utrzymaniu.

Kluczowe funkcjonalności

Funkcjonalność Opis Status w naszym setupie
Distributed Tracing Przechowywanie i odpytywanie trace’ów z dowolnej aplikacji ✅ Skonfigurowane
TraceQL Język zapytań do trace’ów (podobny do SQL) ✅ Skonfigurowane
Metrics Generator Generowanie metryk z trace’ów (metryki RED, grafy serwisów) ✅ Skonfigurowane
Traces to Metrics Powiązanie trace’ów z metrykami w Grafanie ✅ Skonfigurowane
Traces to Logs Powiązanie trace’ów z logami (Loki) w Grafanie ✅ Skonfigurowane
Traces to Profiles Powiązanie trace’ów z profilami (Pyroscope) w Grafanie ✅ Skonfigurowane
Service Graphs Automatyczna wizualizacja zależności między serwisami ✅ Skonfigurowane
TraceQL Metrics (Drilldown) Metryki w czasie rzeczywistym z zapytań TraceQL ✅ Skonfigurowane
Multi-protocol Ingestion OTLP, Jaeger, Zipkin, OpenCensus ✅ Skonfigurowane
MCP Server Serwer Model Context Protocol dla asystentów AI ✅ Skonfigurowane

Tryby wdrożenia

  • Monolithic mode
    • Wszystkie komponenty w jednym procesie
    • Dobre dla: lokalnego developmentu, małych obciążeń (~20GB trace’ów/dzień)
    • Może skalować się horyzontalnie przez gossip ring
  • Simple Scalable (domyślny)
    • Rozdziela ścieżki odczytu i zapisu
    • Dobre dla: do kilku TB/dzień
  • Microservices mode (nasz setup)
    • Każdy komponent wdrożony oddzielnie
    • Najlepsze dla: produkcji, high availability, dużej skali
    • Pełna kontrola nad skalowaniem każdego komponentu

Komponenty

Microservices mode

Distributor

  • Punkt wejścia dla ingescji trace’ów — przyjmuje spany w wielu formatach (OTLP, Jaeger, Zipkin, OpenCensus)
  • Pod spodem korzysta z warstwy receiverów z frameworka OpenTelemetry Collector
  • Routuje spany do Ingesterów przez hashowanie traceID i użycie rozproszonego consistent hash ringa
  • Zalecany format to OTel Proto (OTLP) ze względu na wydajność — dlatego Grafana Alloy używa OTLP exportera/receivera do wysyłania spanów do Tempo
  • Stateless — można skalować niezależnie

Ingester

  • Odbiera spany od Distributora i partycjonuje atrybuty spanów/zasobów do schematu Parquet w celu wydajnego odczytu
  • Grupuje trace’y w bloki przez skonfigurowany okres czasu lub do osiągnięcia maksymalnego rozmiaru bloku
  • Generuje bloom filtry i indeksy dla każdego bloku, a następnie flushuje wszystko do backend object storage
  • Struktura bloków w storage:
    <bucketname>/<tenantID>/<blockID>/meta.json
                                     /index
                                     /data
                                     /bloom_0 ... bloom_n
    
  • W skalowanych wdrożeniach tworzy mechanizmy redundancji (niedostępne w trybie monolitycznym)
  • Uczestniczy w gossip ringu do synchronizacji stanu klastra
  • Hostuje procesory Metrics Generatora

Query Frontend

  • Główny interfejs zapytań — obsługuje wyszukiwanie trace’ów po ID (GET /api/traces/<traceID>) oraz filtrowanie przez TraceQL
  • Sharduje przestrzeń wyszukiwania — dzieli przestrzeń blockID na konfigurowalne shardy
  • Rozrzuca shardowane requesty na jeden lub więcej Querierów równolegle, żeby przyspieszyć odpowiedź
  • Łączy dane spanów zwrócone z wielu Querierów w jedną spójną odpowiedź
  • Zapewnia kolejkowanie zapytań, retry i opcjonalne cachowanie
  • Gdy osiągnięty zostanie limit trace’ów — zwraca dotychczasowe wyniki i anuluje pozostałe requesty do Querierów

Querier

  • Wykonuje faktyczne przeszukiwanie danych w blokach, żeby znaleźć pasujące spany
  • Odpytuje Ingestery o ostatnio przyjęte trace’y (jeszcze nie zflushowane do storage)
  • Pobiera bloom filtry i indeksy z backend storage, żeby efektywnie zlokalizować trace’y w blokach object storage
  • To podejście z dwóch źródeł zapewnia dostęp zarówno do świeżych, jak i historycznych danych
  • Zapytania powinny zawsze trafiać do Query Frontend, a nie bezpośrednio do Queriera
  • Więcej Querierów = szybsze odpowiedzi na zapytania

Compactor

  • Uruchamiany w zaplanowanych interwałach — kompresuje, deduplikuje i reorganizuje bloki zapisane przez Ingestery
  • Uwzględnia dane w ramach konkretnych trace’ów, żeby zminimalizować przyszłą przestrzeń wyszukiwania
  • Wymusza polityki retencji — usuwa dane po upływie skonfigurowanego czasu życia
  • Zmniejsza koszty storage i poprawia wydajność zapytań
  • Stopniowo zastępowany przez architekturę Scheduler/Worker (patrz niżej)

Scheduler & Worker (nowa architektura)

  • Zaprojektowane, żeby ostatecznie zastąpić Compactor bardziej deterministycznym podejściem z mniejszą duplikacją
  • Scheduler: odpowiada za planowanie i śledzenie zadań przydzielanych Workerom. Powinien działać tylko jeden scheduler naraz
  • Worker: łączy się ze Schedulerem przez gRPC, odbiera i wykonuje przydzielone zadania (obecnie kompakcja i retencja), raportuje status z powrotem
  • Workery utrzymują blocklistę dla wszystkich tenantów (wcześniej odpowiedzialność Compactora) i koordynują odpytywanie tenantów przez ring
  • Migracja: skaluj Workery w górę, jednocześnie skalując Compactor do zera, żeby uniknąć konfliktów

Metrics Generator

  • Opcjonalny komponent generujący metryki z danych trace’ów
  • Procesory:
    • span-metrics: metryki RED (Rate, Errors, Duration) per serwis/operacja
    • service-graphs: zależności między serwisami
    • local-blocks: metryki TraceQL dla widoku Drilldown
  • Wysyła wygenerowane metryki do endpointu remote write (Mimir/Prometheus)

Gateway

  • Reverse proxy (Nginx)
  • Routuje ruch HTTP/gRPC do odpowiednich komponentów
  • Pojedynczy punkt wejścia dla zewnętrznego dostępu

results matching ""

    No results matching ""