7.04. Справочник по Tempo
Справочник по Tempo
Grafana Tempo — это масштабируемая, экономически эффективная система распределённого трассирования с открытым исходным кодом, разработанная Grafana Labs. Она предназначена для хранения, поиска и анализа трассировок в микросервисных архитектурах. Tempo не индексирует все атрибуты спанов, а вместо этого использует внешние сигналы (логи и метрики) для поиска идентификаторов трассировок, что снижает стоимость хранения и упрощает эксплуатацию.
Tempo тесно интегрируется с экосистемой Grafana: пользователи могут переходить от графиков в Prometheus или логов в Loki к конкретным трассировкам в Tempo без переключения между инструментами. Архитектура Tempo основана на компонентах, которые можно развернуть как единый бинарник (monolithic mode) или как распределённую систему (microservices mode).
Архитектурные компоненты Tempo
Distributor
Принимает входящие трассировки от клиентов (например, OpenTelemetry Collector), проверяет их корректность и перенаправляет в Ingester. Поддерживает несколько протоколов приёма данных:
- OTLP/gRPC
- OTLP/HTTP
- Jaeger Thrift (UDP и HTTP)
- Zipkin
Конфигурация получателей указывается в блоке distributor.receivers.
Ingester
Буферизует входящие спаны в памяти, группирует их по трассировкам и записывает в хранилище (обычно объектное хранилище, например S3, GCS или MinIO). Ingester управляет жизненным циклом блоков трассировок и отвечает за их фиксацию (flushing).
Querier
Обрабатывает запросы на поиск трассировок по trace ID. Он запрашивает данные из объектного хранилища и из памяти активных Ingester'ов, объединяя результаты.
Query-Frontend
Оптимизирует и параллелизует запросы к Querier'у. Поддерживает кэширование и разбиение временных диапазонов на подзапросы.
Compactor
Выполняет фоновую компактификацию блоков трассировок: объединяет мелкие блоки в более крупные, удаляет дубликаты и применяет политики хранения (retention). Это снижает нагрузку на хранилище и ускоряет поиск.
Ingester-querier (в monolithic-режиме)
В режиме одного процесса функции Ingester и Querier объединены.
Конфигурационный файл (tempo.yaml)
Основной конфигурационный файл Tempo структурирован по модулям. Ниже приведены ключевые секции и параметры.
server
Настройки HTTP/gRPC сервера Tempo.
http_listen_port: порт для HTTP-эндпоинтов (по умолчанию 3200).grpc_listen_port: порт для gRPC-эндпоинтов (по умолчанию 9095).log_level: уровень логирования (debug,info,warn,error).
distributor
Управляет приёмом трассировок.
receivers: список поддерживаемых протоколов. Пример:receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
http:
endpoint: "0.0.0.0:4318"max_recv_msg_size: максимальный размер входящего сообщения (в байтах).tenants: конфигурация мультитенантности (если используется).
ingester
Параметры буферизации и записи.
max_block_duration: максимальная длительность временного блока перед фиксацией (например,30m).flush_check_period: интервал проверки необходимости фиксации блоков (например,1m).complete_block_timeout: время ожидания завершения блока перед принудительной фиксацией.
storage
Определяет тип и параметры хранилища.
trace: секция для хранения трассировок.backend: тип хранилища (local,s3,gcs,azure,swift).- Для
s3:s3:
bucket: "my-tempo-traces"
endpoint: "s3.amazonaws.com"
access_key: "..."
secret_key: "..."
insecure: false - Для
local:local:
path: "/tmp/tempo/blocks"
compactor
compaction: включить/выключить компактификацию (true/false).block_retention: срок хранения блоков (например,48h).compaction_cycle: интервал выполнения компактификации (например,1h).
querier
frontend_worker: настройки взаимодействия с Query-Frontend.search_enabled: разрешить поиск по атрибутам (требует дополнительного индекса; по умолчаниюfalse).
query_frontend
search: параметры поискового API.cache: конфигурация кэша (Redis, Memcached и др.).
Режимы развёртывания
Monolithic
Все компоненты работают в одном процессе. Подходит для тестирования и небольших сред.
- Запуск:
tempo -config.file=tempo.yaml - Минимальная конфигурация содержит только
server,distributor,ingester,storage.
Microservices
Каждый компонент работает как отдельный сервис. Используется в production.
- Требует оркестрации (Kubernetes, Docker Compose).
- Позволяет масштабировать компоненты независимо.
Форматы трассировок и совместимость
Tempo принимает трассировки в следующих форматах:
- OpenTelemetry (OTLP) — рекомендуемый стандарт.
- Jaeger — через Thrift (UDP/HTTP) или gRPC.
- Zipkin — через HTTP.
Каждая трассировка состоит из одного или нескольких спанов. Спан содержит:
trace_id— глобальный идентификатор трассировки.span_id— уникальный идентификатор спана.parent_span_id— ссылка на родительский спан.name— имя операции.start_timeиend_time— временные метки.attributes— произвольные пары ключ-значение (например,http.method,db.statement).events— временные события внутри спана (например, исключения).status— результат операции (OK,ERROR).
Поиск трассировок
Tempo поддерживает два основных способа поиска:
По trace ID
Прямой поиск по известному идентификатору. Это самый быстрый и ресурсоэффективный способ.
По атрибутам (только при включённом search)
Требует настройки querier.search_enabled: true и наличия индекса (например, через Elasticsearch или Tempo Search backend). Включает поиск по таким полям, как:
service.nameoperationduration- произвольные теги (
http.status_code,user.idи т.д.)
Мониторинг и наблюдаемость самого Tempo
Tempo экспортирует метрики Prometheus, логи и внутренние трассировки [[1]]. В репозитории Tempo доступен mixin, содержащий:
- Готовые дашборды Grafana.
- Правила алертинга.
- Рекомендации по мониторингу.
Ключевые метрики:
tempo_ingester_flush_queue_length— длина очереди фиксации.tempo_querier_query_duration_seconds— время выполнения запросов.tempo_distributor_received_spans_total— общее количество принятых спанов.
Ограничения и лучшие практики
- Не добавляйте избыточные атрибуты в спаны — это увеличивает объём данных и стоимость хранения.
- Используйте объектное хранилище для production-развёртываний.
- Настройте retention policy через
compactor.block_retention. - Избегайте частых flush-операций — они создают множество мелких блоков.
- При использовании Kubernetes применяйте Helm-чарты (например, от Bitnami) для упрощения развёртывания.
Командная строка Tempo
Tempo может запускаться с помощью CLI-команд. Основные флаги:
-config.file <path>— путь к YAML-конфигурации.-target <component>— запуск конкретного компонента (например,distributor,ingester,querier). Используется в микросервисном режиме.-mem-ballast-size-mbs <int>— размер «балласта» памяти для стабилизации сборщика мусора Go.-log.level <level>— уровень логирования (debug,info,warn,error).-server.http-listen-port <port>— HTTP-порт сервера.-server.grpc-listen-port <port>— gRPC-порт сервера.
Пример запуска monolithic-режима:
tempo -config.file=/etc/tempo.yaml
Пример запуска только Ingester’а:
tempo -target=ingester -config.file=/etc/tempo.yaml
Helm-чарт и Kubernetes-параметры
Tempo официально поддерживается через Helm-чарт от Grafana Labs. Ключевые настройки в values.yaml:
Общие параметры
fullnameOverride: переопределение имени релиза.image.repository,image.tag: образ и тег контейнера.replicas: количество реплик (для компонентов, поддерживающих масштабирование).
Компоненты
Каждый компонент имеет свой блок:
distributor:
replicas: 2
resources:
requests:
memory: "512Mi"
cpu: "200m"
ingester:
replicas: 3
persistence:
enabled: true
size: "10Gi"
querier:
replicas: 2
compactor:
enabled: true
resources:
requests:
memory: "1Gi"
Хранилище
storage.type:s3,gcs,azure,filesystem.- Для S3:
storage:
s3:
bucket: "my-tempo-traces"
endpoint: "s3.us-east-1.amazonaws.com"
access_key: "..."
secret_key: "..."
Ингрессы и сервисы
ingress.enabled: включить Ingress.service.type: тип сервиса (ClusterIP,LoadBalancer,NodePort).
Интеграция с Grafana
Tempo глубоко интегрирован с Grafana:
- В интерфейсе Grafana можно перейти к трассировке из графика метрик или лога.
- Поддерживается поиск по trace ID напрямую в панели Explore.
- Возможна визуализация трассировок в виде временной шкалы (timeline), DAG (Directed Acyclic Graph) и таблицы спанов.
Требования:
- Grafana версии 7.4+.
- Установленный datasource Tempo в Grafana.
- При использовании Loki/Prometheus — настроенные связи между сигналами (например, label
traceIDв Loki должен совпадать сtrace_idв Tempo).
Интеграция с OpenTelemetry Collector
OpenTelemetry Collector — основной способ отправки трассировок в Tempo.
Пример экспортера в otelcol-config.yaml:
exporters:
otlp/tempo:
endpoint: "tempo-distributor:4317"
tls:
insecure: true
service:
pipelines:
traces:
receivers: [jaeger, zipkin]
exporters: [otlp/tempo]
Поддерживаемые получатели (receivers):
otlpjaegerzipkinopencensus
Формат хранения трассировок (Parquet + WAL)
Tempo использует собственный формат хранения:
- Спаны буферизуются в WAL (Write-Ahead Log) на диске.
- После завершения трассировки данные сериализуются в Parquet-файлы и загружаются в объектное хранилище.
- Parquet выбран за эффективность сжатия и возможность выборочного чтения колонок.
Структура блока в хранилище:
<tenant>/<block_id>/
├── meta.json
├── index.parquet
└── traces.parquet
Файл index.parquet содержит только trace_id и временные метки — это позволяет быстро находить нужный блок без полного сканирования.
Поиск по атрибутам (TraceQL)
Начиная с Tempo 2.0+, доступен язык запросов TraceQL — аналог PromQL для трассировок.
Примеры запросов:
- Найти все трассировки с сервисом
auth-service:{service.name="auth-service"} - Найти медленные трассировки (>1s):
{duration > 1s} - Комбинированный запрос:
{service.name="api-gateway" && http.status_code=500}
Для работы TraceQL требуется:
- Включённый
search_enabled: true. - Настроенный search backend (встроенная база или внешняя, например Elasticsearch).
Параметры производительности и масштабирования
Память
- Ingester потребляет ~1–2 ГБ RAM на 100 тыс. активных трассировок.
- Querier требует меньше памяти, но зависит от объёма одновременных запросов.
Диск
- WAL должен быть на быстром SSD/NVMe.
- Размер WAL регулируется через
ingester.wal.config.segment_size_bytes.
Сеть
- Distributor должен быть защищён от DDoS (например, через rate limiting в Nginx или Istio).
- gRPC-соединения между компонентами должны использовать keepalive.
Масштабирование
- Distributor: горизонтально масштабируется без состояния.
- Ingester: масштабируется с учётом consistent hashing по
trace_id. - Querier: полностью stateless, легко масштабируется.
Пример минимальной конфигурации (tempo.yaml)
server:
http_listen_port: 3200
grpc_listen_port: 9095
distributor:
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
ingester:
max_block_duration: 30m
wal:
path: /tmp/tempo/wal
compactor:
compaction:
block_retention: 48h
storage:
trace:
backend: local
local:
path: /tmp/tempo/blocks
query_frontend:
search:
duration_slo: 5s
Рекомендации по эксплуатации
- Не используйте
localbackend в production — только объектное хранилище. - Настройте мониторинг через Prometheus и алерты на основе mixin’ов Tempo.
- Регулярно обновляйте Tempo — проект активно развивается.
- При высокой нагрузке включите кэширование в Query-Frontend (Redis).
- Избегайте отправки трассировок без
service.name— это затрудняет анализ. - Используйте sampling (например, через OpenTelemetry Collector), если объём данных велик.