30

Kafka 集群中的 Kafka 控制器负责管理分区领导者和复制。

如果 Kafka 集群中有 100 个代理,控制器是否只是一个 Kafka 代理?那么在 100 个经纪人中,控制者是领导者吗?

你怎么知道哪个经纪人是控制器?

Kafka Controller 的管理对于 Kafka 系统管理是否至关重要?

4

3 回答 3

27

控制器是 Kafka 代理之一,它还负责选举分区领导者的任务(除了通常的代理功能)。

控制器只是一个经纪人吗?

一次只有 1 个控制器。

在内部,每个代理都尝试在 zookeeper (/controller) 中创建一个临时节点。第一个成功,成为控制器。其他人只是得到一个适当的异常(“节点已经存在”),并在控制器节点上观察。当控制器死亡时,临时节点被移除,并通知观察代理。再次,其中第一个注册成功的临时节点成为新的控制器,其他人将再次得到“节点已存在”异常并继续等待。

你怎么知道谁是 Kafka 的控制器?

当一个新的控制器被选举出来时,它会被 zookeeper 获得一个“控制器时代”号。代理知道当前的控制器纪元,并且如果他们从具有较旧编号的控制器接收到消息,他们知道忽略它。

控制器是领导者吗?

不是真的..每个分区都有自己的领导者。当一个 broker 死掉时,控制器会检查所有需要新领导者的分区,确定新领导者应该是谁(只是同步副本列表中的随机副本,即该分区的ISR)并向所有包含这些分区的新领导者或现有追随者的代理。

新领导者现在知道他们需要开始为客户的生产者和消费者请求提供服务,而追随者现在知道他们需要开始从新领导者那里进行复制。

于 2018-09-20T13:50:43.427 回答
26

在 Kafka 集群中,单个代理充当活动控制器,负责分区和副本的状态管理。因此,在您的情况下,如果您有一个包含 100 个代理的集群,其中一个将充当控制器。

有关集群控制器职责的更多详细信息,请参见此处

为了找到哪个代理是集群的控制器,您首先需要通过 ZK CLI 连接到 Zookeeper:

./bin/zkCli.sh -server localhost:2181 

然后get是控制器

[zk: localhost:2181(CONNECTED) 0] get /controller

输出应如下所示:

{"version":1,"brokerid":100,"timestamp":"1506423376977"}
cZxid = 0x191
ctime = Tue Sep 26 12:56:16 CEST 2017
mZxid = 0x191
mtime = Tue Sep 26 12:56:16 CEST 2017
pZxid = 0x191
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x15ebdd241840002
dataLength = 56
numChildren = 0

Zookeeper 是 Kafka 集群状态的存储。它用于一开始或当前控制器崩溃时的控制器选举。当主题的分区领导代理失败/崩溃时,控制器还负责告诉其他副本成为分区领导。

于 2018-03-28T05:48:42.447 回答
8

Kafka 控制器是 Kafka 集群的大脑。它监控经纪人的活跃度并对经纪人的失败采取行动。

集群中只有一个 Kafka 控制器。控制器是集群中的 Kafka 代理之一,除了通常的代理功能外,还负责在现有代理离开集群或代理加入集群时选举分区领导者。

通过在 Zookeeper 中创建一个名为“/controller”的临时节点,集群中启动的第一个代理将成为 Kafka 控制器。当其他 broker 启动时,他们也会尝试在 Zookeeper 中创建该节点,但会收到“节点已存在”异常,通过该异常他们知道集群中已经选举了一个 Controller。

当 Zookeeper 没有收到来自 Controller 的心跳消息时,Zookeeper 中的临时节点将被删除。然后它通过 Zookeeper watcher 通知集群中的所有其他代理 Controller 已离开,从而再次开始新 Controller 的新选举。所有其他代理将再次尝试创建一个临时节点“/controller”,第一个成功的将被选为新的控制器。

一个集群中可能有多个控制器。考虑在当前 Kafka 控制器(“Controller_1”)上发生长时间 GC(垃圾收集)的情况,因为 Zookeeper 在配置的时间内没有收到来自控制器的心跳消息。这会导致“/controller”节点从 Zookeeper 中删除,并且集群中的另一个代理被选为新的 Controller(“Controller_2”)。

在这种情况下,我们在集群中有 2 个控制器“Controller_1”和“Controller_2”。“Controller_1”GC 已完成,它可能会尝试在 Zookeeper 中写入/更新状态。“Controller_2”也会尝试写入/更新 Zookeeper 中的状态,这可能导致 Kafka 集群与旧 Controller 和新 Controller 的写入不一致。

为了避免这种情况,每次进行 Controller 选举时都会生成一个新的“epoch”。每次选举出一个控制器,它通过 Zookeeper 条件增量操作接收一个新的更高的 epoch。

这样,当旧控制器(“Controller_1”)尝试更新某些内容时,Zookeeper 将当前纪元与旧控制器在其写入/更新请求中发送的旧纪元进行比较,它只是忽略它。集群中的所有其他代理也知道当前的控制器纪元,如果它们从旧控制器接收到具有较旧纪元的消息,它们也会忽略它。

于 2021-01-29T18:20:49.643 回答