Что такое offset в Apache Kafka и для чего он нужен?

«Что такое offset в Apache Kafka и для чего он нужен?» — вопрос из категории Брокеры сообщений, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Offset — это целочисленный идентификатор, присваиваемый каждому сообщению в рамках партиции Kafka. Он служит для отслеживания позиции потребителя (consumer) в партиции.

Основное назначение:

  • Отслеживание прогресса: Потребитель хранит (коммитит) offset последнего успешно обработанного сообщения. Это позволяет после перезапуска продолжить чтение с того же места, не теряя данные и не обрабатывая их повторно.
  • Гарантия доставки: Управление offset — основа семантики "at-least-once" или "exactly-once" доставки сообщений.

Как это работает:

  1. Каждая партиция — это упорядоченный, неизменяемый журнал (log).
  2. Сообщения в журнале получают последовательные offset (0, 1, 2, ...).
  3. Потребитель читает сообщения по порядку, начиная с сохранённого offset.
  4. После обработки сообщений потребитель коммитит новый offset (обычно в топик __consumer_offsets).

Пример кода (Java) с ручным управлением offset:

Properties props = new Properties();
// Отключаем авто-коммит
props.put("enable.auto.commit", "false");

KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("my-topic"));

while (true) {
    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
    for (ConsumerRecord<String, String> record : records) {
        // Обработка сообщения
        processRecord(record);
    }
    // Ручной коммит offset для всех обработанных сообщений в этом poll
    consumer.commitSync();
}

Важные аспекты:

  • Идемпотентность: Повторное чтение с одного offset приведёт к повторной обработке тех же сообщений. Необходима идемпотентная обработка или точное управление коммитом.
  • Управление: Offset может коммититься автоматически (риск потери данных при сбое) или вручную (позволяет контролировать момент "подтверждения" обработки).
  • Хранение: Offset хранится отдельно от данных сообщения, что позволяет независимо перемещаться по журналу разным потребителям.