Ошибка потребителя Кафки: координатор маркировки мертв

у меня есть тема с 10 разделами в кластере Kafka 0.10.0.1. У меня есть приложение, которое порождает несколько потоков потребителей. Для этой темы я создаю 5 потоков. Много раз в моих журналах приложений я вижу эту запись

INFO :: AbstractCoordinator:600 - Marking the coordinator x.x.x.x:9092
(id:2147483646 rack: null) dead for group notifications-consumer

тогда есть несколько записей, говорящих (Re-)joining group notifications-consumer. Впоследствии я также вижу одно предупреждение, говорящее

Auto commit failed for group notifications-consumer: Commit cannot be completed since
the group has already rebalanced and assigned the partitions to another member. This means
that the time between subsequent calls to poll() was longer than the configured
max.poll.interval.ms, which typically implies that the poll loop is spending too much time 
message processing. You can address this either by increasing the session timeout
or by reducing the maximum size of batches returned by poll() with max.poll.records.

теперь я уже настроил свою потребительскую конфигурацию так

props.put("max.poll.records", 200);
props.put("heartbeat.interval.ms", 20000);
props.put("session.timeout.ms", 60000);

Итак, даже после правильной настройки конфиг я все еще получаю эту ошибку. Во время перебалансировки наше приложение полностью не реагирует. Пожалуйста помочь.

1 ответов


С session.timeout.ms вы контролируете только тайм-ауты из-за сердцебиений, это означает, что прошло session.timeout.ms миллисекунды с момента последнего сердцебиения, и кластер объявляет вас как мертвый узел и запускает перебалансировку.

до КИП-62 сердцебиение было отправлено в рамках опроса, но теперь перемещается в определенный фоновый поток, чтобы избежать выселения из кластера, если вы занимаете больше времени, чем session.timeout.ms позвонить другому poll(). Отделяя пульс конкретный поток отделяет обработку от сообщения кластеру о том, что вы работаете, но это привело к риску возникновения ситуаций "livelock", в которых процесс жив, но не прогрессирует, поэтому, кроме того, делает сердцебиение независимым от poll новый тайм-аут был введен, чтобы гарантировать, что потребитель был жив и развивается. В документации говорится об этом о реализации pre KIP-62:

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

изменения, внесенные КИП-62, включают в себя:

развязка тайм-аута обработки: мы предлагаем ввести отдельный локально принудительный тайм-аут для обработки записей и фоновый поток, чтобы сохранить сеанс активным до истечения этого тайм-аута. Мы называем этот новый тайм-аут "тайм-аут процесса" и выставляем его в конфигурации потребителя как max.опрос.интервал.ms. Эта конфигурация устанавливает максимальную задержку между клиентом звонки на опрос()

из журналов вы выложили я думаю, что вы можете быть в этой ситуации, ваше приложение занимает больше времени, чем max.poll.interval.ms (5 мин по умолчанию) для обработки 200 опрошенных записей. Если вы находитесь в этом сценарии, вы можете только уменьшить еще больше max.poll.records или увеличить max.poll.interval.ms.

PD:

на max.poll.interval.ms конфигурация, которая появляется в вашем журнале, от (по крайней мере) Кафки 0.10.1.0, поэтому я предполагаю, что вы делаете небольшую ошибку.

обновление

поправьте меня, если я понял вас неправильно, но в своем последнем комментарии Вы говорили, что создаете 25 потребителей (например, 25 org.apache.kafka.clients.consumer.KafkaConsumer если вы использовали java) и suscribing их к N различным темам, но используя то же самое group.id. Если это правильно, вы увидите rebalacing каждый раз KafkaConsumer запускается или останавливается, потому что он отправит JoinGroup или LeaveGroup сообщение (см. соответствующую Кафка протоколом), содержащей group.id и member.id (the member.id не является хостом, поэтому два потребителя, созданные в одном процессе, все равно будут иметь разные идентификаторы). Обратите внимание, что это сообщение не содержит информации о подписке на тему (хотя эта информация должна быть в брокерах, но Кафка не использует ее для перебалансировки). Поэтому каждый раз, когда кластер получает JoinGroup или LeaveGroup на group.id X, он вызовет перебалансировку для всех потребителей с тем же group.id Х.

если вы начинаете 25 потребителей с тем же group.id вы увидите перебалансировку, пока не будет создан последний потребитель, и соответствующий перебалансировка заканчивается (если вы продолжаете видеть это, вы можете остановить потребителей).

я этот вопрос пару месяцев назад.

если у нас есть два KafkaConsumer, используя ту же группу.id (работает в том же процессе или в двух разных процессах), и один из них закрыт, он запускает перебалансировку в другом KafkaConsumer, даже если они были подписаны на разные темы. Я полагаю, что брокеры должны учитывать только группу.id для перебалансировки, а не подписанные темы,соответствующие паре (group_id, member_id) LeaveGroupRequest, но мне интересно, является ли это ожидаемым поведением или это что-то, что должно быть улучшено? Я думаю, что это, вероятно, первый вариант, чтобы избежать более сложной перебалансировки в брокере и учитывая, что решение очень простое, т. е. просто использовать разные идентификаторы групп для разных KafkaConsumer, которые подписываются на разные темы, даже если они работают в одном процессе.


когда происходит перебалансировка, мы видим повторяющиеся сообщения

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

я разделился на две группы, теперь внезапно проблема исчезла с прошлых 2 часов.

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

здесь большой разговор о различных сценариев равновесия.