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

14. Kafka

Как Kafka обеспечивает семантику «ровно один раз» (exactly-once processing), и какие проблемы при этом возникают?​

Middle

Ответ: Kafka обеспечивает семантику «ровно один раз» (EOS) с помощью:

  • Идемпотентные продюсеры: Гарантируют, что повторные попытки не приведут к появлению дубликатов.
  • Транзакции: Группируют несколько операций Kafka в единую атомарную единицу.
  • Управление смещениями потребителей: При использовании Kafka Streams или транзакционных потребителей смещения фиксируются атомарно.

Проблемы:

  • Требуется идемпотентность на стороне потребителя.
  • Необходимо включить acks=all, enable.idempotence=true у продюсеров.
  • Увеличение задержки из-за транзакционных записей.

Подробное руководство по Kafka


Какова роль High-Water Mark (HW) в Kafka и как это влияет на потребителей?​

Middle

Ответ:

  • High-Water Mark (HW) — это последнее смещение, которое считается «зафиксированным» и может быть прочитано потребителями.
  • Если реплика-последователь отстает, она не будет выбрана лидером, так как у нее нет HW.
  • Потребители не могут читать незафиксированные данные (за HW), что обеспечивает согласованность.

Сложный сценарий: Если брокер упадет до того, как HW будет обновлен, некоторые зафиксированные сообщения могут временно исчезнуть, но они будут восстановлены после выбора лидера.


Как Kafka обрабатывает сбой лидера и что происходит с сообщениями «в полете»?​

Middle

Ответ:

  • Kafka использует ZooKeeper/KRaft для выбора нового лидера из синхронных реплик (ISR).
  • Сообщения «в полете» (ack=1 или ack=0) могут быть потеряны, если они не были реплицированы.
  • Если acks=all, сообщение считается безопасным только в том случае, если лидер успешно реплицировал его в ISR до падения.
  • Незафиксированные сообщения (ниже HW) могут быть потеряны в сценарии отказа.

Крайний случай: Если нет синхронных реплик, Kafka приостановит запись, чтобы предотвратить потерю данных, пока последователь не догонит лидера.


Объясните уплотнение логов (log compaction) в Kafka. Чем оно отличается от политик удержания (retention policies)?​

Middle

Ответ:

  • Уплотнение логов сохраняет как минимум одну версию для каждого ключа, удаляя старые версии.
  • Политики удержания (log.retention.ms, log.retention.bytes) удаляют сообщения по времени или размеру, независимо от ключа.

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

  • Уплотнение полезно для журналов изменений (последнее состояние) в базах данных.
  • Удержание полезно для журналов событий (например, отслеживание активности пользователей).

Каверзный вопрос: Что произойдет, если потребитель никогда не прочитает уплотненный топик? Если потребитель был отключен слишком долго, он может потерять некоторые исторические обновления, так как старые сообщения удаляются.


Как Kafka предотвращает дублирование сообщений при повторных попытках продюсера?​

Middle

Ответ: Kafka использует идемпотентных продюсеров для предотвращения дубликатов при повторах:

  • К каждому сообщению прикрепляется порядковый номер.
  • Брокер запоминает последний подтвержденный порядковый номер для каждого продюсера.
  • Если продюсер повторно отправляет сообщение, Kafka отбрасывает дубликаты.

Сложный сценарий: Если продюсер перезапускается и получает новый ID, старое отслеживание сбрасывается, и могут появиться дубликаты.


Как Kafka обрабатывает обратное давление (backpressure), когда потребители отстают?​

Middle

Ответ:

  • Потребители отстают, когда обрабатывают сообщения медленнее, чем они поступают.
  • Kafka обрабатывает обратное давление с помощью API pause()/resume() в Kafka Consumer.
  • Если отставание слишком велико:
    • Увеличьте количество потребителей в группе.
    • Увеличьте вычислительную мощность (например, пакетная обработка).
    • Используйте ограничение скорости на стороне продюсера.

В чем разница между синхронными репликами (ISR), неснхронными репликами (OSR) и недореплицированными разделами?​

Middle

Ответ:

  • ISR (In-Sync Replicas): Реплики, которые догнали лидера.
  • OSR (Out-of-Sync Replicas): Отстающие последователи.
  • Under-Replicated Partitions (URP): Любой раздел, где количество ISR меньше фактора репликации.

Каверзный вопрос: Если у топика фактор репликации 3, а ISR = 1, что это значит? Только один брокер синхронизирован (высокий риск потери данных). Если лидер упадет, может не оказаться безопасных реплик для продвижения.


Почему «нечистый» выбор лидера (unclean leader election) опасен в Kafka?​

Senior

Ответ:

  • Когда unclean.leader.election.enable=true, последователь, не находящийся в синхронизации, может быть выбран лидером, что потенциально приведет к потере зафиксированных сообщений.
  • Это может вызвать несогласованность данных между продюсерами и потребителями.
  • В продакшене всегда держите это значение false, если только доступность не важнее согласованности.

Как Kafka Streams эффективно обрабатывает состояния?​

Senior

Ответ:

  • Использует RocksDB как встроенную базу данных для локального хранения состояния.
  • Использует топики журналов изменений (changelogs) для восстановления состояния после сбоев.
  • Использует punctuation() для периодической обработки без полной переобработки.

Сложный случай: Если приложение Kafka Streams перезапускается и топик журнала изменений удален, все локальное состояние теряется и должно быть вычислено заново.


Как можно отслеживать и отлаживать отставание потребителя (consumer lag) в Kafka?​

Senior

Ответ:

  • Используйте kafka-consumer-groups.sh для проверки отставания.
  • Мониторьте метрики JMX (kafka.consumer:type=ConsumerLag).
  • Настройте оповещения на основе отставания в Prometheus/Grafana/New Relic.

Сложный сценарий отладки: Если отставание растет, несмотря на несколько экземпляров, проверьте:

  • «Штормы» перебалансировки из-за неэффективного назначения разделов.
  • Медленная десериализация (оптимизируйте размер сообщения).
  • Паузы GC у потребителя (настройте параметры JVM).

Как реализовать распределенное логирование с использованием Kafka в PHP-приложении?​

Senior

Ответ: Kafka — отличный буфер для логов (стек ELK/Graylog). Чтобы реализовать это в PHP:

  • Используйте php-rdkafka в качестве продюсера.
  • В вашем приложении вместо записи напрямую в файл или базу данных отправляйте события логов в топик Kafka (например, app_logs).
  • Настройте продюсера для использования небольших пакетов (queue.buffering.max.ms), чтобы избежать высоких накладных расходов на каждое сообщение.
  • Используйте уровни логов (например, ERROR, INFO) в качестве ключей разделов для эффективной группировки логов.
  • На другой стороне используйте потребителя Kafka или инструмент вроде Logstash для передачи логов в Elasticsearch.

Подробное руководство по Kafka