Раздел 26 · Data Engineering

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

junior~15 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

В уроке про лог мы выяснили, что чтение в Kafka ничего не удаляет. Тогда откуда берётся место на диске? Координаты курьеров «Гонца» приходят каждые пять секунд от сотни курьеров, это сотни тысяч записей в сутки. Если хранить их вечно, диск кончится. Сегодня разберём, как Kafka удаляет старое и почему делает это не по одной записи.

Видеорегистратор

В машине стоит видеорегистратор. Он пишет видео не одним бесконечным файлом, а кусками по минуте: файл заполнился, закрылся, начался следующий. Карта памяти небольшая, поэтому регистратор хранит, скажем, последние два часа. Когда место нужно, он удаляет самый старый файл целиком. Отрезать от файла первые десять секунд он не умеет и не пытается.

И ещё одно: файл, который пишется прямо сейчас, регистратор не удаляет никогда, даже если запись в нём началась давно.

Kafka хранит данные так же.

Сегменты

Партиция на диске это не один файл, а цепочка файлов-сегментов. Записи дописываются в последний сегмент. Его называют активным. Когда активный сегмент стал слишком большим или слишком старым, Kafka закрывает его и начинает новый.

Когда закрывать, решают две настройки топика:

НастройкаПо умолчаниюСмысл
segment.bytes1 ГБзакрыть сегмент, когда он дорос до этого размера
segment.ms7 днейзакрыть сегмент, когда ему столько времени

Сегмент закрывается только в момент новой записи: пока в партицию ничего не пишут, активный сегмент так и остаётся активным. Ещё деталь: в Kafka 4.x segment.bytes не может быть меньше 1 МБ, настоящий брокер отвечает на меньшее значение ошибкой Value must be at least 1048576. Поэтому в песочнице мы закрываем сегменты по времени, через segment.ms.

Retention: сколько хранить

Правило хранения называют retention. Его тоже задают две настройки:

  • retention.ms. Сколько хранить по времени. По умолчанию 7 дней. Сегмент удаляется, когда самой свежей записи в нём больше этого срока.
  • retention.bytes. Сколько хранить по размеру, для каждой партиции отдельно. По умолчанию -1, то есть без ограничения.

Удаляется всегда весь закрытый сегмент. Отсюда три следствия, о которых новички узнают на собственном опыте:

  • Данные живут дольше срока. Сегмент удаляется, когда устарела его самая свежая запись. Первые записи сегмента успевают прожить почти retention.ms + segment.ms.
  • Активный сегмент бессмертен. Если в топик неделю никто не пишет, последний сегмент неделю и лежит, хотя срок давно вышел.
  • Партиция бывает больше retention.bytes. Kafka удаляет сегмент, только если без него партиция всё ещё не меньше лимита. Поэтому запас до одного сегмента сверх лимита это норма.

Проверку настоящий брокер делает раз в пять минут, это log.retention.check.interval.ms. Песочница удаляет сразу, как только прошло время.

Номер первой живой записи партиции называют началом лога. Его показывает kafka-get-offsets --time -2, а конец лога обычный kafka-get-offsets.

Настраивают retention при создании топика или на лету:

kafka-topics.sh --bootstrap-server localhost:9092 --create --topic courier-gps \
  --config retention.ms=600000 --config segment.ms=60000
kafka-configs.sh --bootstrap-server localhost:9092 --alter \
  --entity-type topics --entity-name courier-gps --add-config retention.bytes=1048576

Обе команды мы проверили на Kafka 4.3.1.

урок из курса

Урок из курса «Data Engineering». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.