【发布时间】:2020-01-11 01:18:12
【问题描述】:
引用 here 的 docker-compose.yml 文件允许在 3 台机器上轻松设置 ZooKeeper 和 Kafka。
让我们将 3 台机器的 IP 地址分别为 1.1.1.1、1.1.1.2 和 1.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宕机,我也可以生产到kafka2或kafka3成功。 - 如果
zk1宕机,我仍然可以从kafka1消费。 - 如果
zk1宕机,来自kafka2或kafka3的消费会阻塞,直到zk1 备份。可以在此处检索在zk1关闭时发送但由kafka2或kafka3标记为发送成功的消息。
基于这些观察:
- 假设您只需要在
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