Перейти к содержимому

Data Retention

Data Retention в Kafka — это политика хранения сообщений, определяющая, как долго и в каком объёме данные сохраняются в топике. Сообщения не удаляются после прочтения (как в очередях), а живут заданное время (retention.ms) или до превышения размера партиции (retention.bytes), после чего удаляются целыми сегментами — файлами на диске, что эффективно и безопасно. Альтернативная политика — компактизация (cleanup.policy=compact) — оставляет только последнее сообщение для каждого ключа, превращая лог в таблицу актуальных состояний. Гибридный режим (compact,delete) сначала компактизирует, затем удаляет по времени/объёму. Компактизация подходит для CDC, хранения текущих состояний и таблиц (KTable), но не для логов и метрик, где важна каждая запись.

Введение: Почему сообщения не живут вечно

Представьте, что вы ведёте дневник. Каждый день вы пишете новую страницу. Через год дневник занимает целую полку. Через десять лет — целый шкаф. Бесконечно хранить всё невозможно. Что-то нужно выкидывать.

В Kafka то же самое. Сообщения не удаляются после прочтения (как в очередях). Они хранятся, пока не истечёт срок или не превышен объём. Это называется Data Retention — политика хранения данных.

Для системного аналитика retention — это компромисс между доступностью истории и стоимостью хранения. Хранить долго — можно перечитывать старые события, но нужно много места. Хранить коротко — место экономится, но история теряется.

Retention по времени

Как работает

Сообщения хранятся фиксированное время. По истечении срока они удаляются.

ПараметрПо умолчаниюТипичные значения
log.retention.hours168 (7 дней)24 часа, 7 дней, 30 дней
log.retention.minutesНет5 минут, 60 минут
log.retention.msНетТочная настройка (миллисекунды)
Настройка на уровне топика:
  retention.ms=604800000  # 7 дней

Что происходит:
  - Сообщение создано в 12:00
  - Текущее время 12:00 + 7 дней
  - Сообщение удалено

Пример

Топик: user_events
retention.ms: 86400000 (24 часа)

Сообщения:
  10:00: сообщение 1
  12:00: сообщение 2
  14:00: сообщение 3

Завтра в 10:00: сообщение 1 удалено
Завтра в 12:00: сообщение 2 удалено
Завтра в 14:00: сообщение 3 удалено

Retention по объёму

Как работает

Хранится фиксированный объём данных на партицию. При превышении старые сообщения удаляются.

ПараметрПо умолчаниюТипичные значения
log.retention.bytes-1 (без ограничения)1 ГБ, 10 ГБ, 100 ГБ
Настройка на уровне топика:
  retention.bytes=1073741824  # 1 ГБ на партицию

Что происходит:
  - Объём партиции = 500 МБ
  - Новое сообщение + 600 МБ
  - Всего стало 1.1 ГБ
  - Старые сообщения удаляются, пока объём не станет ≤ 1 ГБ

Пример

Топик: logs
retention.bytes: 104857600 (100 МБ)

Партиция:
  Сообщения 1-100: 90 МБ
  Сообщение 101: 15 МБ (всего 105 МБ)

Удаляются самые старые сообщения, пока объём не станет ≤ 100 МБ

Сегменты (Segments)

Что такое сегмент

Лог партиции разбит на сегменты — файлы на диске.

Партиция 0:
  сегмент 0: offsets 0-999 (1 ГБ)  # активный (пишем сюда)
  сегмент 1: offsets 1000-1999 (1 ГБ)  # закрыт
  сегмент 2: offsets 2000-2999 (1 ГБ)  # закрыт

Параметры сегментов

ПараметрЗначение по умолчаниюЧто делает
log.segment.bytes1 ГБМаксимальный размер сегмента
log.segment.ms7 днейМаксимальный возраст сегмента

Зачем нужны сегменты

  • Удаление происходит целыми сегментами (эффективно)
  • Активный сегмент не удаляется (только закрытые)
  • Сегменты позволяют управлять retention без блокировок

Удаление (Deletion)

Как удаляются сообщения

    graph LR
    A[Активный сегмент] -->|не трогаем| A
    B[Закрытый сегмент] -->|проверка retention| B
    B -->|пора| C[Удаление сегмента]
  

Почему сегментами, а не по одному сообщению: Удаление целого файла быстрее и безопаснее, чем удаление отдельных записей внутри файла.

Когда происходит удаление

Фоновый поток (cleaner thread) периодически проверяет:

  • Не истекло ли время retention
  • Не превышен ли объём retention
  • Удаляет закрытые сегменты, которые подпадают под условия

Компактизация (Compaction)

Что это

Вместо удаления старых сообщений по времени или объёму, Kafka оставляет только последнее сообщение для каждого ключа.

Как работает

Исходный лог (ключ → значение):
  key: user_123 → value: {"name": "Иван", "status": "active"}
  key: user_123 → value: {"name": "Иван", "status": "blocked"}
  key: user_123 → value: {"name": "Иван", "status": "deleted"}
  key: user_456 → value: {"name": "Петр", "status": "active"}

После компактизации:
  key: user_123 → value: {"name": "Иван", "status": "deleted"}  # последнее
  key: user_456 → value: {"name": "Петр", "status": "active"}   # последнее

Параметры

ПараметрЗначение по умолчанию
cleanup.policydelete (по времени/объёму)
cleanup.policy=compactВключить компактизацию
min.cleanable.dirty.ratio0.5

Когда использовать компактизацию

СценарийПример
Хранение последнего состоянияТекущий статус пользователя
Таблица в Kafka (KTable)KTable в Kafka Streams
Change Data Capture (CDC)Логи изменений БД

Компактизация не подходит для

СценарийПочему
События, где важна каждая записьЛоги, метрики, события
Данные без ключейНет ключа — нет компактизации

Комбинированные политики

delete + compact

cleanup.policy=compact,delete

Сначала компактизация (оставляем последнее по ключу), потом удаление по времени/объёму.

Пример: Состояние пользователя

Топик: user_state
cleanup.policy: compact
retention.ms: 604800000 (7 дней)

Что получаем:
  - Остаётся только последнее состояние каждого пользователя
  - Если пользователь не обновлялся 7 дней — удаляется полностью

Настройка retention

Уровни настройки

УровеньПараметр
Глобальный (брокер)log.retention.hours, log.retention.bytes
Топикretention.ms, retention.bytes
Сегментlog.segment.bytes, log.segment.ms

Приоритет

Топик → глобальный. Если на топике задано, то глобальное игнорируется.

Мониторинг retention

Метрики

МетрикаЧто показывает
kafka.log.LogSizeТекущий размер лога
kafka.log.NumLogSegmentsКоличество сегментов
kafka.log.OldestSegmentMsВозраст самого старого сегмента

Алерты

СитуацияДействие
Размер лога растёт бесконечноПроверить, работает ли retention
Размер лога резко упалПроверить, не удалили ли нужные данные

Влияние на производительность

Удаление

ФакторВлияние
Частота удаленийФоновый поток, нагрузка на диск
Количество сегментовМного сегментов = больше файлов = медленнее

Компактизация

ФакторВлияние
Частота компактизацииНагрузка на CPU, диск
Размер логаЧем больше лог, тем дольше компактизация

Практические рекомендации

СценарийРекомендация
Логи, метрикиcleanup.policy=delete, retention.ms=7d
События для аналитикиcleanup.policy=delete, retention.ms=30d
Состояние (таблицы)cleanup.policy=compact
CDC (Change Data Capture)cleanup.policy=compact,delete
Высокая нагрузкаУвеличить log.segment.bytes (меньше сегментов)
Много маленьких сообщенийУменьшить log.segment.bytes (быстрее компактизация)

Распространённые ошибки

Ошибка 1: Слишком долгий retention

Хранят логи 5 лет. Место кончается.

Решение: Определить реальные потребности. Логи за прошлый год вряд ли кому-то нужны.

Ошибка 2: Слишком короткий retention

Хранят 1 час. Аналитик не успевает прочитать.

Решение: Узнать требования потребителей. Минимум — время, за которое самый медленный потребитель читает данные.

Ошибка 3: Компактизация без ключей

Включили компактизацию, но сообщения без ключей. Ничего не компактизируется.

Решение: Компактизация работает только с ключами.

Ошибка 4: Компактизация для логов

Включили компактизацию для логов. Потеряли историю.

Решение: Для логов и метрик — cleanup.policy=delete.

Ошибка 5: Игнорирование размера сегментов

Маленькие сегменты → много файлов → медленнее.

Решение: Настроить log.segment.bytes под объём данных.

Резюме

  1. Data Retention — политика хранения сообщений в Kafka. Сообщения не удаляются после прочтения, а живут определённое время.

  2. По времени (retention.ms): сообщения удаляются через N миллисекунд.

  3. По объёму (retention.bytes): сообщения удаляются, когда партиция превышает размер.

  4. Сегменты — лог разбит на файлы. Удаление происходит целыми сегментами.

  5. Компактизация (cleanup.policy=compact): оставляет только последнее сообщение для каждого ключа.

  6. Гибрид (compact,delete): сначала компактизация, потом удаление по времени.

  7. Компактизация подходит для хранения последнего состояния, таблиц, CDC.

Проверка знаний

Вопрос 1 из 4
Что такое data retention в Kafka?
Почему retention важен для аналитика и архитектора?
Что произойдёт после истечения retention?
Когда особенно полезен длительный retention?

Вопросы, где были ошибки