Чем group.instance.id отличается от group.id, зачем нужен member.id, каковы преимущества статического членства в группе потребителей перед динамическим и какие механизмы Kafka обеспечивают ребалансировку клиентских приложений.
Еще раз про группы потребителей Apache Kafka
Напомним, группы потребителей в Apache Kafka нужны для логического объединения нескольких потребителей с целью повышения надежности потоковой системы. В один момент времени только один потребитель из всей группы с одинаковым group.id фактически получает данные раздела топика Kafka. Это обеспечивает отказоустойчивость потоковой системы. Например, если возникнет сбой на активном потребителе, и он перестанет отправлять координатору группы heartbeat-сигнал, произойдет перебалансировка потребителей и активным станет другой. При этом вся потоковая система из приложений-продюсеров, Kafka и приложений-потребителей продолжит работать. Чтобы избежать дублирования данных, т.е. не получать все сообщения с самого начала, конфигурацию потребителя auto.offset.reset следует установить в значение latest вместо earliest. Подробнее об этом мы писали здесь и здесь.
Вообще в Kafka есть две стратегии членства в группах: статическая и динамическая. При статическом членстве выполняется следующий набор действий:
- когда к группе присоединяется новый потребитель, брокер узнает об этом;
- далее брокер меняет состояние группы потребителей с RUNNING на PREPARE_REBALANCE;
- как только группа потребителей отреагирует на изменение состояния подготовки к ребалансировке, брокер меняет состояние на COMPLETING_REBALANCE;
- после выполнения ребансировки состояние снова восстанавливается до RUNNING.
Чтобы выполнить этот процесс брокер отслеживает параметр member.id, который обеспечивает уникальную идентификацию каждого члена группы потребителей.
При динамическом членстве в момент ребалансировки, когда новый потребитель отправляет запрос на присоединение к группе со специальным пока неизвестным идентификатором UNKNOWN_MEMBER_ID. Благодаря этому брокер идентифицирует потребителя как нового члена группы и генерирует для него новый идентификатор члена группы.
Во время перезапуска клиента это происходит для всех членов группы, т.к. при отправке запроса на присоединение к группе включается UNKNOWN_MEMBER_ID. Значение member.id не сохраняется, и запускается ребалансировка, поскольку брокер идентифицирует всех потребителей как новых. Таким образом, member.id управляется брокером Kafka, тогда как group.instance.id настраивается на стороне приложения-потребителя.
При использовании динамического членства в приложении с большим объемом локального состояния ребалансировка одного раздела топика из одного экземпляра потребителя в другой означает передачу огромного объема данных. Если приложение-потребитель создало большой объем локального состояния и происходит переназначение раздела, это состояние необходимо сохранить и перенести на новый узел. А если данных состояния очень много, то процесс будет медленным. Избежать этого поможет статическое членство потребителей.
Потребитель со статическим членством — это потребитель с настроенным group.instance.id в дополнение к его member.id, управляемому брокером. Параметр group.instance.id сохраняет уникальность потребителя при перебалансировке. Поэтому даже при перезагрузке потребителя из группы со статическим членством брокер узнает его по значению group.instance.id и не будет назначать новое членство. Это позволяет избежать повторной ребалансировки и отставания скорости потребления от скорости публикации.
Хотя процесс перебалансировки занимает немного времени (от нескольких секунд до минуты), все потребители на этот период приостанавливают обработку данных. Но приложения-продюсеры продолжают отправлять данные в топик Kafka. В результате этого момент обработки события потребителем отстает от момента, когда это событие произошло в реальном мире на стороне продюсера. Продолжительность ребалансировки зависит от количества разделов, т.к. каждый потребитель, должен отозвать, а затем восстановить связь с координатором для назначения разделов. Чем больше разделов, тем больше времени на это понадобится.
Таким образом, статическое членство потребителей значительно ускоряет последовательные обновления и делает тяжеловесные stateful-приложения более эффективными. Поскольку идентификаторы потребителей в группе сохраняется в group.instance.id, им не нужно выполнять повторную балансировку при удалении и повторном присоединении. А единственная задержка ребалансировки будет связана с перезапуском узла.
Для реализации статического членства в группе потребителей, надо задать значение group.instance.id в конфигурации приложения-потребителя.
В заключение отметим, что group.instance.id отличается от group.id. Параметр group.id является идентификатором группы и определяет, к какой группе принадлежит потребитель. А group.instance.id должен быть разным для каждого члена группы потребителей, поскольку он идентифицирует экземпляр потребителя как члена группы. Брокер Kafka сопоставляет group.instance.id с каждым member.id, чтобы обеспечить уникальную идентификацию каждого потребителя. В этом случае свойство member.id служит дополнительной проверкой для статического членства.
Узнайте больше про администрирование и эксплуатацию Apache Kafka для потоковой аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
- Apache Kafka для инженеров данных
- Администрирование кластера Kafka
- Администрирование Arenadata Streaming Kafka
Источники