【问题标题】:Which nodes do you need to specify for bootstrap_servers (Kafka Python) and zookeeper.connect (ZooKeeper)?您需要为 bootstrap_servers (Kafka Python) 和 zookeeper.connect (ZooKeeper) 指定哪些节点?
【发布时间】:2020-01-11 01:18:12
【问题描述】:

引用 heredocker-compose.yml 文件允许在 3 台机器上轻松设置 ZooKeeper 和 Kafka。

让我们将 3 台机器的 IP 地址分别为 1.1.1.11.1.1.21.1.1.3

  • 机器 1:zk1、kafka1
  • 机器 2:zk2、kafka2
  • 机器 3:zk3、kafka3

为每个 zk 实例指定所有 ZooKeeper IP 地址。那就是:

  • zk1: zookeepers=[zk1 (1.1.1.1), zk2 (1.1.1.2), zk3 (1.1.1.3)]
  • zk2: zookeepers=[zk1 (1.1.1.1), zk2 (1.1.1.2), zk3 (1.1.1.3)]
  • zk3: zookeepers=[zk1 (1.1.1.1), zk2 (1.1.1.2), zk3 (1.1.1.3)]

我们对每个 Kafka 实例都做同样的事情:

  • kafka1: zookeepers (KAFKA_ZOOKEEPER_CONNECT)=[zk1 (1.1.1.1), zk2 (1.1.1.2), zk3 (1.1.1.3)]
  • kafka2: zookeepers (KAFKA_ZOOKEEPER_CONNECT)=[zk1 (1.1.1.1), zk2 (1.1.1.2), zk3 (1.1.1.3)]
  • kafka3: zookeepers (KAFKA_ZOOKEEPER_CONNECT)=[zk1 (1.1.1.1), zk2 (1.1.1.2), zk3 (1.1.1.3)]

这很好用。我可以使用kakfa-python 向一个 Kafka 代理发送(生产)并从另一个代理获取它:

from kafka import KafkaProducer, KafkaConsumer

p = KafkaProducer(bootstrap_servers='1.1.1.2:9092')  # Send to one broker
p.send('topic1', b'1')

c = KafkaConsumer('topic1', bootstrap_servers='1.1.1.3:9092', auto_offset_reset='earliest')  # Retrieve from another broker
next(c)  # This retrieves it properly

现在,问题是:

  • (1) 我需要为每个 ZooKeeper 实例指定多少个 ZooKeeper 节点?
  • (2) 我需要为每个 Kafka 实例(代理)指定多少个 ZooKeeper 节点?
  • (3) 我需要为 Kafka 生产者 (bootstrap_servers) 指定多少个 Kafka 代理?
  • (4) 我需要为 Kafka 消费者 (bootstrap_servers) 指定多少个 Kafka 代理?

我已经做了一些实验并阅读了一些内容,但让某人验证会有所帮助(尤其是因为我读过的一些答案仍然来自早期的 Kafka 版本)。

问题 1

每个 zk 实例必须指定所有其他 zk 实例。这是有道理的,因为它定义了整个 zk 集群。不过,我不确定 zk 是否可以进行节点发现,例如:

  • zk1: zookeepers=[zk1, zk2]
  • zk2: zookeepers=[zk2, zk3]
  • zk3: zookeepers=[zk3, zk1]

它自己发现所有其他节点。

问题 2-4

我尝试将kafka1 设置为仅使用zk1

假设我们谈论的是topic1,它有一个分区、一个复制因子,并且在机器 1 上。

观察:

  • 假设 zk1 已启动,我可以生产到 kafka2 并从 kafka3 消费。
  • 如果zk1宕机,我可以成功生产到kafka1
  • 如果zk1宕机,我也可以生产到kafka2kafka3成功。
  • 如果zk1 宕机,我仍然可以从kafka1 消费。
  • 如果zk1 宕机,来自kafka2kafka3 的消费会阻塞,直到zk1 备份。可以在此处检索在zk1 关闭时发送但由kafka2kafka3 标记为发送成功的消息。

基于这些观察:

  • 假设您只需要在bootstrap_servers 中指定at least one broker,但最好还是全部指定。
  • ZooKeeper 关闭时:我们可以生产,但消费者阻塞,因为它需要 ZooKeeper 来跟踪消费者偏移量。 here 对此进行了解释,尽管这仍然是从 2015 年开始的,当时有单独的消费者 API。我认为这里的解释仍然成立。

【问题讨论】:

  • 关于“假设 zk1 启动,我可以生产到 kafka2 并从 kafka3 消费”......您如何验证您的客户生产和消费到/从 2 和 3?因为那不应该是不可能的,因为主题只存在于 1 上。当您指定 2 或 3 作为引导程序时,客户端会收到有关所有 3 个服务器、主题、分区等的元数据。当客户端与主题交互时,它知道它需要与 1 通信,而不是与 2 或 3。

标签: python apache-kafka apache-zookeeper


【解决方案1】:

我对你的问题的看法:

(1) 我需要为每个 ZooKeeper 实例指定多少个 ZooKeeper 节点?

最好的就是所有这些,特别是如果您在 ensemble 中只有 3 个节点。如果您只指定两个,然后执行滚动重启,则每个节点将在重启期间的某个时间点失去与其唯一已知对等点的连接,并且与集成的(间接)连接(嗯,另一个剩余的未知节点)。

(2) 我需要为每个 Kafka 实例(代理)指定多少个 ZooKeeper 节点?

不能说。同样,理想情况下是所有这些。只指定一个最有可能的工作,直到该节点出现故障,即您正在运行一个容错性低的集群。

(3) 我需要为 Kafka 生产者 (bootstrap_servers) 指定多少个 Kafka 代理?

(4) 我需要为 Kafka 消费者 (bootstrap_servers) 指定多少个 Kafka 代理?

理论上只有一个,因为在初始握手期间,Kafka 节点向连接的客户端提供有关所有其他 Kafka 节点的信息。这就是为什么正确指定集群中的 advertised listeners 很重要的原因(这些是客户端可以从“外部”访问节点的所有端点)。握手完成后,您可以关闭该服务器,并假设您的主题有 >1 个复制,您的集群应该仍然可以正常工作。

但是,如果客户端只知道一个引导服务器的地址,如果该服务器出现故障,他们将无法启动与集群的新连接,即容错能力降低。

【讨论】:

    猜你喜欢
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多