Программа курса

Модуль 03 / Урок 13 из 27

Jaeger v2 и ingestion через Kafka

Теория и практика

Две темы «второго уровня»: как устроен современный Jaeger v2 под капотом и как строится приём через Kafka — схема для крупных систем, где нельзя терять трейсы при сбоях.

Jaeger v2: Collector как основа

Jaeger v2 — это дистрибуция OTel Collector: стандартные компоненты OTel + компоненты Jaeger (хранилище, query, сэмплинг). Один бинарник jaeger, конфиг — YAML в OTel-стиле:

# jaeger-v2-config.yaml (упрощённо)
extensions:
  jaeger_storage:
    backends:
      es_default:
        elasticsearch:
          server_urls: http://elasticsearch:9200
          index_prefix: jaeger
  jaeger_query:
    storage:
      traces: es_default

receivers:
  otlp:
    protocols:
      grpc: {}
      http: {}

processors:
  batch: {}

service:
  extensions: [jaeger_storage, jaeger_query]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [jaeger_storage_exporter]
  • Приём — OTLP (всё остальное — совместимость);
  • Query/UI — порт 16686, как раньше;
  • Любые процессоры Collector доступны в том же пайплайне: это и есть главная выгода — tail sampling, фильтры и маршрутизация «в одном флаконе» с бэкендом.

Зачем Kafka в цепочке трейсов

Прямая схема «Collector → хранилище» уязвима: остановка записи в ES/Cassandra = потеря входящих трейсов (буферы конечны). Kafka добавляет буфер с диском и развязку скоростей:

SDK ─► OTel Collector (agent) ─► Kafka topic "traces" ─► ingester ─► Jaeger storage (ES/Cassandra)
                                                                    └► Jaeger query/UI
  • Пик нагрузки не теряется: если хранилище отстаёт, спаны копятся в топике;
  • Несколько потребителей: в Jaeger пишем, параллельно — аналитический пайплайн (spanmetrics, ML-обучение) из того же топика;
  • Отказоустойчивость записи: acks/репликация Kafka дают гарантию доставки до журнала.

Как это реализовано

  • Collector: exporter kafka — пишет спаны (прототип OTLP) в топик;
  • v1: компонент jaeger-ingester — читал топик и писал в хранилище;
  • v2: Collector-приёмник kafka в составе той же дистрибуции + exporter в jaeger_storage — та же схема, но единым бинарником и конфигом;
  • Партиционирование: по trace ID — сохраняется порядок спанов внутри трейса, нагрузка распределяется по партициям.

Цена Kafka-схемы

  • Ещё один кластер в эксплуатации (если нет общего);
  • Двойная запись (Kafka + хранилище) — задержка появления трейса в UI растёт (секунды);
  • Настройка retention топика: должны переживать самый длинный сбой записи в хранилище.
💡 Практический порог: до ~10–20 тыс. трейсов/сек прямая схема с нормальным кластером хранилища обычно справляется. Kafka — когда объёмы больше или требование «не терять трейсы при плановых рестартах хранилища» непреложно.

Практика

  1. Соберите схему с Kafka в docker-compose: Collector (kafka exporter) → single-broker Kafka → Collector (kafka receiver) → Jaeger. Найдите свои трейсы в UI.
  2. Остановите «записывающий» Collector на 2 минуты под нагрузкой, поднимите: убедитесь, что трейсы доезжают из буфера Kafka.
  3. Сравните задержку появления трейса в UI: прямая схема против Kafka-схемы.
Мини-квиз

1. Что нового в архитектуре v2? — Jaeger — дистрибуция OTel Collector: единый бинарник, OTel-конфиг, OTLP как основной протокол.

2. Почему партиционирование по trace ID? — Спаны одного трейса идут в одну партицию: порядок и консистентное чтение.

3. Главная причина ставить Kafka? — Гарантированный буфер между приёмом и хранилищем + параллельные потребители.