为什么 Kafka 消费者连接到 zookeeper,生产者从 broker 获取元数据?

Why do Kafka consumers connect to zookeeper, and producers get metadata from brokers?

为什么消费者连接到 zookeeper 来检索分区位置?并且 kafka 生产者必须连接到其中一个代理来检索元数据。

我的观点是,当每个代理都已经拥有所有必要的元数据来告诉生产者发送消息的位置时,zookeeper 到底有什么用?经纪人不能将同样的信息发送给消费者吗?

我能理解为什么代理有元数据,以便在每次向它们发送新消息时不必与 zookeeper 建立连接。 zookeeper 是否有我缺少的功能?我发现很难想出在 kafka 集群中真正需要 zookeeper 的原因。

首先,只有高级消费者才需要zookeeper。 SimpleConsumer 不需要 zookeeper 工作。

高级消费者需要 zookeeper 的主要原因是跟踪消耗的偏移量和处理负载平衡。

现在更详细。

关于偏移跟踪,想象一下以下场景:您启动一个消费者,消费了 100 条消息,然后关闭了消费者。下次启动消费者时,您可能希望从上次使用的偏移量(即 100)恢复,这意味着您必须在某处存储最大使用偏移量。这是 zookeeper 发挥作用的地方:它存储每个 group/topic/partition 的偏移量。因此,下次您启动消费者时,它可能会询问 "hey zookeeper, what's the offset I should start consuming from?"。 Kafka 实际上正在朝着能够不仅在 zookeeper 中存储偏移量,而且在其他存储中也能存储偏移量的方向发展(目前只有 zookeeperkafka 偏移量存储可用,我不确定 kafka 存储已完全实现)。

关于负载平衡,产生的消息量可能非常大,无法由一台机器处理,您可能希望在某个时候增加计算能力。假设您有一个包含 100 个分区的主题,并且您有 10 台机器来处理这些消息。这里实际上出现了几个问题:

  • 这10台机器之间应该如何划分分区?
  • 如果其中一台机器挂掉会怎样?
  • 如果您想添加另一台机器会怎样?

再一次,这里是 zookeeper 发挥作用的地方:它跟踪组中的所有消费者,并且每个高级消费者都订阅了该组中的更改。关键是当一个消费者出现或消失时,zookeeper 会通知所有消费者并触发重新平衡,以便他们几乎平均地分割分区(例如平衡负载)。这样它可以保证如果其中一个消费者死亡,其他消费者将继续处理该消费者拥有的分区。

kafka 0.9+ 引入了新的 Consumer API。新消费者不需要连接到 Zookeeper,因为组平衡由 kafka 本身提供。

你是对的,消费者不需要连接到 ZooKeeper,因为 kafka 0.9 release。他们重新设计了 api 并引入了新的消费者客户端:

the 0.9 release introduces beta support for the newly redesigned consumer client. At a high level, the primary difference in the new consumer is that it removes the distinction between the “high-level” ZooKeeper-based consumer and the “low-level” SimpleConsumer APIs, and instead offers a unified consumer API.

Finally this completes a series of projects done in the last few years to fully decouple Kafka clients from Zookeeper, thus entirely removing the consumer client’s dependency on ZooKeeper.