Як моніторити lag консьюмера
Уявіть чергу в магазині. Касир (consumer) обслужив 80 покупців, а в черзі стоїть ще 200. Lag = 200 — це скільки покупців ще чекають. Якщо lag росте — касир не справляється, потр...
🟢 Junior Level
Просте визначення
Consumer lag — це різниця між останнім повідомленням в партиції Kafka і останнім повідомленням, яке обробив консьюмер. Показує наскільки консьюмер “відстає”.
Аналогія
Уявіть чергу в магазині. Касир (consumer) обслужив 80 покупців, а в черзі стоїть ще 200. Lag = 200 — це скільки покупців ще чекають. Якщо lag росте — касир не справляється, потрібно відкрити ще касу.
Візуалізація
Partition 0:
Log End Offset (останнє в Kafka): 1000
Committed Offset (оброблено): 800
────────────────────────────────────────
Consumer Lag: 200
[0......100......200......800|←200→|1000]
|----- оброблено -----| lag |
Як подивитися lag
# Kafka CLI утиліта
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--describe --group order-service
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
order-service orders 0 800 1000 200
order-service orders 1 750 900 150
order-service orders 2 900 950 50
Total lag: 400 повідомлень
Що означає lag
| Lag | Що означає | Що робити |
|---|---|---|
| 0 | Консьюмер обробив все | Нічого, все чудово |
| 1–100 | Нормальне відставання | Спостерігати |
| 100–1000 | Консьюмер сповільнився | Перевірити throughput |
| 1000+ | Консьюмер не справляється | Масштабувати |
| Росте швидко | Критична проблема | Alert + investigate |
(ці значення залежать від throughput — lag потрібно оцінювати РАЗОМ з producer rate. Lag 1000 при 100 msg/s = 10 секунд відставання; при 1M msg/s = несуттєво)
Коли це важливо
- Production monitoring — завжди моніторити lag
- Scaling decisions — коли додавати консьюмери
- Health checks — lag = індикатор здоров’я
- SLA monitoring — гарантія часу обробки
🟡 Middle Level
Як працює lag calculation
Lag = LogEndOffset - CommittedOffset
LogEndOffset:
- Останній offset записаний в партицію
- Оновлюється при кожному producer send
- Зберігається на брокері
CommittedOffset:
- Останній offset закоммічений консьюмером
- Зберігається в __consumer_offsets topic
- Оновлюється при consumer.commitSync/Async
Lag calculation:
- Обчислюється external tool (не самою Kafka)
- Kafka broker надає LogEndOffset
- Monitoring tool читає committed offsets
- Lag = різниця між ними
Інструменти моніторингу
1. Kafka CLI
# Усі consumer groups
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list
# Деталі конкретної групи
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--describe --group order-service
2. Burrow (LinkedIn)
# Burrow HTTP API
GET http://burrow-server:8000/v3/kafka/cluster/consumer/order-service/status
Response:
{
"status": "OK",
"partitions": [
{
"topic": "orders",
"partition": 0,
"status": "OK",
"current_lag": 200,
"max_lag": 300
}
]
}
Burrow status values: | Status | Значення | | —— | ——————— | | OK | Lag зменшується або 0 | | WARN | Lag стабільний, високий | | ERROR | Lag росте | | STOP | Consumer не коммітить | | STALL | Lag не змінюється | | REWIND | Offset moved backwards|
3. Prometheus + kafka_exporter
# docker-compose.yml
services:
kafka-exporter:
image: danielqsj/kafka-exporter
command: ['--kafka.server=kafka:9092']
ports: ["9308:9308"]
Сценарії використання
Scenario 1: Lag росте лінійно
Time Lag
10:00 100
10:05 300
10:10 500
→ Linear growth = consumer повільніший за producer
Root cause: consumer processing slow, GC pauses, network latency
Action: Scale consumers або optimize processing
Scenario 2: Lag spike затем recovery
Time Lag
10:00 100
10:05 5000 ← spike
10:15 100 ← recovery
Root cause: Temporary broker unavailability, network partition resolved
Action: Investigate spike cause, may not need scaling
Scenario 3: Lag росте експоненціально
Time Lag
10:00 100
10:15 3200
10:20 12800
→ Exponential = consumer completely stuck
Root cause: Poison pill message, deadlock, external dependency down
Action: URGENT — find root cause, may need to skip messages
🔴 Senior Level
Глибокі внутрішності
Lag calculation internals
Kafka broker:
Partition State:
- LogEndOffset: offset який наступне повідомлення отримає
- HighWatermark: offset останнього закомміченого повідомлення (всі ISR)
- LastStableOffset: для транзакційних повідомлень
Consumer:
CommittedOffset: зберігається в __consumer_offsets topic
Position: наступний offset для читання (може бути попереду committed)
Lag (per partition) = LogEndOffset - CommittedOffset
Offset Commit Lag vs Processing Lag
Offset Commit Lag:
CommittedOffset = 800
ProcessingOffset = 850 (оброблено але не закоммічено)
LogEndOffset = 1000
"Visible lag" = 1000 - 800 = 200
"Real lag" = 1000 - 850 = 150
Різниця = 50 messages in-flight (оброблено, не закоммічено)
Edge Cases
1. Lag = 0 але consumer не працює:
Сценарій:
Consumer обробив до offset 1000
Немає нових повідомлень за останні 10 хв
Lag = 0
Виглядає OK, але consumer може бути мертвий!
Рішення:
1. Monitor consumer heartbeat
2. Monitor processing rate
3. Monitor "time since last commit"
4. Burrow status: STOP якщо немає heartbeat
2. Lag spike при rebalancing:
Lag spike під час ребалансу = normal
Lag recovery після ребалансу = healthy
Monitoring:
Ignore lag spikes < 5 min duration
Alert on lag spike > 10 min without recovery
3. Transactional messages і Lag:
Consumer з isolation.level = read_committed:
Бачить тільки committed messages
Lag розраховується коректно
Consumer з isolation.level = read_uncommitted:
Бачить всі messages включаючи uncommitted
Lag = misleading!
Рішення: monitoring повинен використовувати LastStableOffset
для read_committed consumers
Highload Best Practices
✅ Lag per partition monitoring (не тільки total)
✅ Lag growth rate monitoring (deriv/lag rate)
✅ Lag + throughput + producer rate разом
✅ Burrow status monitoring (OK/WARN/ERROR/STOP/STALL)
✅ Alert thresholds по severity (warning, critical)
✅ Runbook для lag investigation
✅ Auto-scaling на lag thresholds (KEDA, custom HPA)
✅ Historical lag data (trend analysis)
✅ Transactional message awareness (LastStableOffset)
❌ Lag без context (throughput, producer rate)
❌ Lag без alerting (useless metric)
❌ Lag total без per-partition breakdown
❌ Lag monitoring без runbook
❌ Lag = 0 = healthy assumption (consumer може бути stopped)
Архітектурні рішення
- Lag — leading indicator — росте до того як users impacted
- Lag + throughput + error rate — three pillars of consumer health
- Burrow status > lag number — status trend більш actionable ніж absolute lag
- Auto-scaling on lag — proactive scaling, not reactive
- Lag per partition — partition-level visibility critical
Резюме для Senior
- Lag = LogEndOffset - CommittedOffset, але нюанси (in-flight, transactional)
- Burrow status (OK/WARN/ERROR/STOP/STALL/REWIND) більш інформативний ніж lag value
- Lag growth rate — більш actionable ніж absolute lag
- Lag spike при rebalancing — normal, не alert
- Lag = 0 не значить consumer healthy (check heartbeat, throughput)
- Transactional messages — use LastStableOffset для lag calculation
- Auto-scaling on lag thresholds — KEDA для Kubernetes
- Production runbook для lag investigation — обов’язковий
🎯 Шпаргалка для інтерв’ю
Обов’язково знати:
- Consumer Lag = LogEndOffset - CommittedOffset — ключова метрика здоров’я консьюмера
- Lag per partition критичний: total lag приховує проблемні партиції (hot key)
- Burrow status: OK, WARN, ERROR, STOP, STALL, REWIND — інформативніший ніж absolute lag
- Lag growth rate (deriv) — більш actionable ніж absolute lag value
- Lag = 0 не значить healthy: consumer може бути stopped, немає нових повідомлень
- Інструменти: kafka-consumer-groups.sh, Burrow, Prometheus + kafka_exporter, Grafana
- Auto-scaling на lag thresholds: KEDA для Kubernetes
Часті уточнюючі запитання:
- Lag=0 — це завжди OK? — Ні, consumer може бути dead; check heartbeat і throughput.
- Що означає REWIND в Burrow? — Offset moved backwards (replay, reset, або data loss).
- Lag spike при ребалансингу — це проблема? — Ні, expected behavior; ignore < 5 min duration.
- Як визначити hot partition? — Lag imbalance across partitions: одна відстає, інші OK.
Червоні прапорці (НЕ говорити):
- «Lag=0 значить все чудово» — consumer може бути stopped
- «Тільки total lag достатньо» — приховує partition-level problems
- «Lag spike при ребалансі — критична проблема» — normal behavior
- «Burrow не потрібен, вистачає CLI» — CLI = point-in-time, Burrow = trend analysis
Пов’язані теми:
- [[12. Що таке offset в Kafka]]
- [[13. Як працює commit offset]]
- [[24. Як обробляти помилки при читанні повідомлень]]
- [[25. Що таке DLQ (Dead Letter Queue)]]