Частые ошибки при работе с Apache Kafka — симптомы, причины и пошаговые решения.
Лидер партиции переместился на другой брокер во время перезапуска или переназначения разделов. Клиент использует устаревшие метаданные и направляет запросы на брокер, который больше не является лидером.
Консьюмер превысил session.timeout.ms (не отправил heartbeat вовремя) или max.poll.interval.ms (слишком долго обрабатывал записи между вызовами poll()). Это интерпретируется координатором группы как сбой участника и запускает ребалансировку.
Лидер партиции ещё не избран — это типично для только что созданного топика или после того, как ISR опустел и unclean.leader.election.enable=false. Брокер возвращает ошибку, пока контроллер не завершит выборы.
Число живых синхронизированных реплик (ISR) стало меньше min.insync.replicas. Это происходит, когда брокеры падают, сетевая связность между брокерами нарушена, или фолловер не успевает за лидером и вылетает из ISR по таймауту replica.lag.time.max.ms.
Зафиксированное смещение больше не существует в топике: данные были удалены политикой хранения (retention.ms истёк или диск заполнен), либо зафиксированное смещение указывает за пределы текущего конца лога (LEO). Чаще всего это происходит, когда консьюмер-группа долго не работала и offsets.retention.minutes истёк.
Размер сообщения превышает один из трёх лимитов: max.request.size на продюсере (по умолчанию 1 МБ), message.max.bytes на брокере (по умолчанию 1 МБ) или max.message.bytes на уровне топика. Все три значения должны быть согласованы — несоответствие хотя бы одного вызывает ошибку.
Брокер не подтверждает запросы за время delivery.timeout.ms (по умолчанию 120 000 мс). Причины: брокер перегружен медленным дисковым I/O или GC-паузами, сетевая задержка слишком высокая, или buffer.memory переполнен из-за высокого темпа продукции.
Ребалансировка завершилась, пока консьюмер обрабатывал записи — координатор присвоил новое поколение группы. Попытка зафиксировать смещения для старого поколения отклоняется. Корневая причина: обработка батча заняла больше времени, чем max.poll.interval.ms.
Топик не существует в кластере. Возможные причины: auto.create.topics.enable=false на брокере (типично для production), опечатка в имени топика, или топик не был создан в рамках процесса деплоя. В production-кластерах автосоздание топиков отключают намеренно.
Несоответствие SSL-конфигурации: клиент не доверяет сертификату брокера (отсутствует CA в truststore), сертификат истёк, имя хоста в сертификате не совпадает с адресом брокера, или между клиентом и брокером несовместимые версии TLS-протокола.
JAR-файл коннектора отсутствует в директориях, указанных в plugin.path воркера, или класс коннектора не находится в пути поиска плагинов. Kafka Connect использует изолированные classloaders для каждого плагина — JAR должен быть в отдельной поддиректории plugin.path.
Sink-задача не может десериализовать входящие сообщения из-за несоответствия конвертера (value.converter) формату данных в топике. Типичные причины: схема изменилась и несовместима с текущей версией в Schema Registry, URL Schema Registry не задан, или сообщения в топике имеют смешанный формат.
Топология Kafka Streams ссылается на входные топики, которые не существуют в кластере. Это происходит при деплое приложения раньше, чем созданы необходимые топики, или при ошибке в именах топиков в конфигурации приложения.
Значение replication.factor при создании топика превышает количество доступных (живых) брокеров в кластере. Kafka не может разместить реплики на несуществующих брокерах, поэтому отклоняет запрос на создание топика.
Один или несколько консьюмеров в группе ведут себя непредсказуемо: зависают, медленно обрабатывают данные или имеют нестабильное сетевое соединение. Каждый сбой запускает новую ребалансировку, не давая группе достичь стабильного состояния. Проблема усугубляется при большом числе партиций и участников группы.
Хип JVM брокера исчерпан. Основные причины: слишком маленький -Xmx для текущей нагрузки, большое число соединений (каждое требует буферов), слишком большой fetch.max.bytes в запросах консьюмеров, или утечка памяти в обработчиках запросов.
SASL настроен в security.protocol, но JVM не может найти класс LoginModule, указанный в JAAS-конфигурации. Типичные причины: JAAS-файл не передан JVM через параметр -Djava.security.auth.login.config, имена секций KafkaServer или KafkaClient написаны с ошибкой, или нужный модуль (krb5, scram) отсутствует в classpath.
Фолловеры не успевают догнать лидера и вылетают из ISR. Причины: перегруженность диска на брокере-фолловере, высокая сетевая задержка между брокерами, неравномерное распределение лидеров (один брокер является лидером для слишком многих партиций), или временный сбой одного брокера.
Файл сегмента лога повреждён — контрольная сумма CRC записей не совпадает. Чаще всего это следствие аварийного отключения без flush данных на диск, аппаратного сбоя (RAID без записи, битый сектор), или файловой системы без journaling.
Два экземпляра продюсера используют одинаковый transactional.id, или новый экземпляр был создан раньше, чем старый завершил свои транзакции. Kafka повышает эпоху продюсера (producer epoch) — старые экземпляры с меньшей эпохой блокируются для предотвращения дублирования сообщений.
Новая версия схемы нарушает режим совместимости, установленный для данного subject в Schema Registry. При BACKWARD-совместимости консьюмеры со старой схемой должны уметь читать данные, записанные с новой. Удаление обязательного поля или изменение типа без значения по умолчанию нарушает это правило.