Learning Platform
Глоссарий Troubleshooting
Урок 05.02 · 20 мин
Продвинутый
LEOHigh WatermarkConsumer LagReplicationISRConsistency

LEO и High Watermark

Когда producer записывает сообщение в Kafka, оно немедленно попадает в лог лидера. Но потребитель не всегда может его прочитать. Между моментом записи и моментом видимости существует временной интервал, обусловленный механизмом репликации. Два понятия управляют этим поведением: LEO (Log End Offset) и High Watermark (HW).


LEO — Log End Offset

LEO (Log End Offset) — это значение, равное следующему офсету, который будет присвоен следующей записи. Иначе говоря: LEO = последний записанный offset + 1.

LEO является per-replica метрикой: каждая реплика партиции ведёт собственный LEO независимо от других.

Пример для партиции с тремя репликами после записи 150 сообщений:

  • Лидер записал все 150 → LEO(Leader) = 150
  • Фолловер 1 успел получить 148 → LEO(Follower-1) = 148
  • Фолловер 2 успел получить 145 → LEO(Follower-2) = 145

Фолловеры всегда отстают от лидера на величину, зависящую от сетевой задержки, производительности диска и нагрузки на брокеры.


High Watermark — граница видимости

High Watermark (HW) — это минимальный LEO среди всех реплик в ISR (In-Sync Replicas). HW — per-partition метрика, которую ведёт лидер.

HW = min(LEO(лидер), LEO(фолловер-1), LEO(фолловер-2), ...)
     где все реплики входят в ISR

В примере выше: HW = min(150, 148, 145) = 145.

HW — это граница: потребители могут читать только сообщения с offset строго меньше HW. Сообщения с offset от 145 до 149 существуют в логе лидера, но невидимы для потребителей.

NOTE

HW называется именем «High Watermark» по аналогии с отметкой уровня воды: это максимальный уровень, до которого «поднялись» все реплики. Потребитель не видит воду выше этой отметки, потому что она ещё не поднялась у всех реплик.


Визуализация: LEO и HW при репликации

LEO и High Watermark
Состояние реплик партиции
Лидер (Broker 1)Лидер: LEO=150. Принял все 150 сообщений от producer. Сообщения 145-149 записаны локально, но ещё не подтверждены фолловерами — потребители их не видят.
Фолловер 1 (Broker 2)Фолловер 1: LEO=148. Отстаёт от лидера на 2 сообщения. Репликация идёт, но есть небольшой лаг. Входит в ISR.
Фолловер 2 (Broker 3)Фолловер 2: LEO=145. Самый медленный из трёх реплик. HW определяется его LEO — именно он ограничивает границу видимости.
HW = min(150, 148, 145) = 145
Consumer читает до HW=145Consumer видит только offset 0-144. Offset 145-149 существует на лидере, но недоступен до тех пор, пока все ISR-реплики не получат эти сообщения и HW не продвинется.

Почему HW защищает от потери данных

Смысл HW — безопасность при смене лидера. Если лидер падает, один из фолловеров становится новым лидером. Если потребитель уже прочитал сообщение с offset 147, а новым лидером становится Фолловер-2 (LEO=145), то сообщений 145-149 у нового лидера нет. Потребитель получил данные, которых больше нет в кластере — это катастрофа.

HW предотвращает это: потребитель не может прочитать сообщение, пока оно не реплицировано на все ISR-реплики. Тогда даже при смене лидера гарантируется, что прочитанные данные присутствуют у нового лидера.

WARNING

При acks=1 producer считает запись успешной после подтверждения только лидером. Такое сообщение попадает в лог лидера, но может не успеть реплицироваться до его падения. HW в этом случае не спасает — сообщение было в логе лидера, но не достигло ISR. Для гарантии durability используйте acks=all с min.insync.replicas >= 2.


Задержка продвижения HW

HW продвигается не мгновенно. После того, как лидер получил сообщение:

  1. Фолловеры периодически опрашивают лидера (fetch request)
  2. Лидер отвечает данными и обновлённым значением HW
  3. Фолловеры записывают данные на диск и обновляют свой LEO
  4. При следующем fetch запросе фолловер сообщает лидеру свой новый LEO
  5. Лидер пересчитывает HW как min всех LEO в ISR
  6. Обновлённый HW отправляется фолловерам при следующем ответе

Этот цикл занимает время, пропорциональное replica.fetch.wait.max.ms (по умолчанию 500 мс). В это время сообщение существует, но невидимо потребителям — это называется «окно нестабильности» (staleness window).


Consumer Lag

Consumer Lag — это разница между последним доступным offset в партиции и текущим committed offset потребителя:

lag = end_offset(partition) - committed_offset(consumer_group, partition)

Если потребитель читает быстро и не отстаёт, lag близок к нулю. Если lag растёт — потребитель не справляется с темпом производителей, и система накапливает задолженность.

Lag измеряется через:

  • kafka-consumer-groups.sh --describe --group my-group
  • Метрики JMX: kafka.consumer:type=consumer-fetch-manager-metrics,attribute=records-lag
  • Инструменты мониторинга: Kafka UI, Burrow, Prometheus + kafka_exporter
TIP

Consumer lag — ключевая SLO-метрика. Алерт при lag > N сообщений часто настраивается через Burrow или kminion. Нормальный lag зависит от приложения: для fraud detection допустимо менее 100 сообщений, для batch ETL — могут быть миллионы.


HW и ISR shrinkage

Если фолловер значительно отстаёт от лидера более чем на replica.lag.time.max.ms (по умолчанию 30 000 мс), он исключается из ISR. После исключения его LEO перестаёт учитываться при вычислении HW.

Это означает: если в ISR остаётся только лидер, HW = LEO лидера, и потребители получают данные практически без задержки. Но durability снижается — при падении лидера новый лидер может иметь меньше данных.

Проверка знанийKnowledge check
Фолловер в ISR начинает сильно отставать из-за перегруженного диска. Что произойдёт с High Watermark и видимостью данных для потребителей?
ОтветAnswer
Пока фолловер остаётся в ISR, его LEO учитывается при вычислении HW. Если фолловер перестаёт продвигать LEO, HW не продвигается вместе с LEO лидера — потребители видят всё меньше новых данных, а consumer lag растёт. Через replica.lag.time.max.ms (по умолчанию 30 секунд) фолловер исключается из ISR. После исключения HW снова начинает следовать за LEO лидера — потребители получают данные быстрее. Но durability снизилась: теперь достаточно одного брокера для продвижения HW.

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 5. Partition с 3 ISR-репликами: лидер LEO=200, фолловер-1 LEO=198, фолловер-2 LEO=195. Какой High Watermark у этой партиции и какой последний offset может прочитать consumer?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5