Хранение и retention: Kafka помнит долго

Урок про то, как долго и почему Kafka держит данные, и как настроить срок их жизни.

Retention — политика, определяющая, как долго событие живёт в логе, прежде чем будет удалено: по времени (retention.ms) или по размеру (retention.bytes).

Зачем это нужно

Вопреки интуиции «очереди», Kafka не удаляет событие после прочтения. Оно живёт, пока его не вытеснит политика retention — часто это дни или недели. Это и делает возможными replay, подключение новых потребителей и восстановление состояния из истории.

Сегменты лога

Партиция физически — это цепочка файлов-сегментов. Активный сегмент дописывается; когда он достигает порога (segment.bytes или segment.ms), он закрывается и начинается новый. Удаление по retention работает посегментно: Kafka удаляет старый сегмент целиком, а не выковыривает отдельные сообщения.

  Партиция P0:
  [сегмент 0..9999][сегмент 10000..19999][активный 20000.. --o]
       ^ старый                                    ^ пишем сюда
  retention истёк -> удаляется весь старый сегмент

Политики retention

ПараметрСмыслПример
retention.msхранить N миллисекунд604800000 (7 дней)
retention.bytesдержать не более N байт на партицию10737418240 (10 ГБ)
cleanup.policydelete или compactdelete (по умолчанию)
# задать retention 7 дней для топика orders
kafka-configs.sh --bootstrap-server localhost:9092 \
  --alter --entity-type topics --entity-name orders \
  --add-config retention.ms=604800000

Почему хранить долго — это нормально

Длинный retention — фича, а не баг. Новый сервис, поднявшийся через неделю, прочитает историю и построит своё состояние. Обнаружив баг, вы переиграете последние дни. Аналитика догонит пропущенное после простоя. Хранение на диске дёшево относительно ценности воспроизводимости.

Как работает под капотом

Фоновый процесс периодически проверяет сегменты на соответствие retention: закрытый сегмент, все сообщения которого старше retention.ms (или вышли за retention.bytes), помечается и удаляется. Активный сегмент не трогают. Поскольку удаление идёт целыми файлами, оно почти бесплатно — никакой дефрагментации лога. Время хранения считается по времени сообщений в сегменте, поэтому реальный срок жизни может слегка превышать retention.ms — пока сегмент не закроется и не «состарится» целиком.

Частые ошибки

  • Слишком короткий retention. Потребитель, отставший на час, не успеет догнать — события удалятся раньше прочтения (потеря на стороне чтения).
  • Бесконечный retention без расчёта диска. Лог растёт, диск брокера заполняется — кластер встаёт.
  • Ждать удаления из середины. Retention режет сегментами, отдельные сообщения не выпиливаются по одному.

Итоги

  • Kafka хранит события по retention (время/размер), а не до первого прочтения.
  • Удаление идёт целыми сегментами — это дёшево; активный сегмент не трогается.
  • Долгое хранение включает replay, подключение новых потребителей и восстановление после простоя.
Проверьте себя
1. Когда Kafka удаляет событие из лога (политика delete)?
AСразу после прочтения
BКогда истекает retention по времени или размеру
CНикогда
DПосле коммита оффсета
2. Как физически происходит удаление по retention?
AПо одному сообщению из середины
BЦелыми закрытыми сегментами-файлами
CПерезаписью нулями
DЧерез ZooKeeper
3. Чем опасен слишком короткий retention?
AРастёт нагрузка на CPU
BОтставший консьюмер не успеет дочитать — события удалятся раньше прочтения
CСообщения дублируются
DЛидер не выбирается