Ответ 1
Прежде всего, zookeeper необходим только для потребителей высокого уровня. SimpleConsumer
не требует использования zookeeper.
Основная причина, по которой zookeeper необходим, чтобы потребитель высокого уровня отслеживал расходованные смещения и обрабатывал балансировку нагрузки.
Теперь более подробно.
Что касается отслеживания смещения, представьте себе следующий сценарий: вы начинаете потребитель, потребляете 100 сообщений и закрываете клиента. В следующий раз, когда вы запустите своего потребителя, вы, вероятно, захотите возобновить свое последнее поглощенное смещение (что равно 100), а это значит, что вы должны где-то хранить максимальное потребление. Здесь, где zookeeper пинает: он хранит смещения для каждой группы/темы/раздела. Таким образом, таким образом, в следующий раз, когда вы начнете свой потребитель, он может спросить: "Эй, зокпер, какое смещение я должен начать потреблять?". Kafka фактически стремится к тому, чтобы хранить смещения не только в zookeeper, но и в других хранилищах (на данный момент доступны только хранилища смещения zookeeper
и kafka
, и я не уверен, что kafka
хранилище полностью реализовано).
Что касается балансировки нагрузки, количество выпущенных сообщений может быть довольно большим, чтобы обрабатывать 1 машину, и вы, вероятно, захотите добавить вычислительную мощность в какой-то момент. Допустим, у вас есть тема со 100 разделами и для обработки этого количества сообщений у вас есть 10 машин. На самом деле возникает несколько вопросов:
- Как эти 10 машин разделяют разделы между собой?
- что произойдет, если одна из машин погибнет?
- Что произойдет, если вы хотите добавить еще одну машину?
И снова, здесь, где zookeeper пинает: он отслеживает всех потребителей в группе, и каждый потребитель высокого уровня подписывается на изменения в этой группе. Дело в том, что, когда потребитель появляется или исчезает, zookeeper уведомляет всех потребителей и вызывает балансировку, чтобы они разделили разделы почти одинаково (например, чтобы сбалансировать нагрузку). Таким образом, он гарантирует, что один из потребителей умирает, другие будут продолжать обрабатывать разделы, принадлежащие этому потребителю.