首页 > 解决方案 > 如果领导者没有死但无法在 Kafka 中接收消息会怎样?特种作战部队?

问题描述

我有 3 个经纪人,3 个分区。每个代理都是一个分区的领导者和所有的 ISR。假设我19092,29092,39092分别在端口上运行代理。

19092 - partition 0
29092 - partition 1
39092 - partition 2

半经纪人测试:

我想这样命名它!因为它只允许 OUTPUT 而不允许 INPUT

现在,我添加了以下 iptables 规则:

iptables -A INPUT -p tcp --dport 29092 -j DROP

在生产者中:

bin/kafka-console-producer --broker-list 10.54.8.172:19092 --topic ftest

上面的 iptables 规则阻止 INPUT 访问,但不限制代理使用 Zookeeper 更新其活动性。所以zookeeper不会认为它已经死了,所以不会为分区1进行leader选举。

但是,由于 RULE 的原因,生产者无法连接到它,因此会引发错误。

org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for ftest-1: 1778 ms has passed since batch creation plus linger time

这是我手动完成的,但可能有其他原因可能会阻止 INPUT 访问(某些恶意软件、DDoS 或其他任何东西)。

在 iptables 规则之前:

Metadata for ftest (from broker 1: 10.54.8.172:19092/1):

 3 brokers:

  broker 2 at 10.54.8.172:29092

  broker 1 at 10.54.8.172:19092

  broker 3 at 10.54.8.172:39092

 1 topics:

  topic "ftest" with 3 partitions:

    partition 2, leader 3, replicas: 3,1,2, isrs: 3,1,2

    partition 1, leader 2, replicas: 2,3,1, isrs: 2,3,1

    partition 0, leader 1, replicas: 1,2,3, isrs: 1,2,3

在 iptables 规则之后:

Metadata for ftest (from broker 1: 10.54.8.172:19092/1):

 3 brokers:

  broker 2 at 10.54.8.172:29092

  broker 1 at 10.54.8.172:19092

  broker 3 at 10.54.8.172:39092

 1 topics:

  topic "ftest" with 3 partitions:

    partition 2, leader 3, replicas: 3,1,2, isrs: 3,1,2

    partition 1, leader 2, replicas: 2,3,1, isrs: 2

    partition 0, leader 1, replicas: 1,2,3, isrs: 1,2,3

由于只有一个领导者而且它已经死了(从某种意义上说它无法接收任何消息),这不是单点故障吗?

我认为,理想情况下,Zookeeper 和 Kafka 代理之间必须有两种方式的通信。不是吗?卡夫卡允许吗?如果是这样,怎么做?

此外,当 29092 被阻止进行 INPUT 访问时,它的 ISR 缩小到 1。

这可能是因为它无法从其他 2 个代理接收任何消息(心跳)。

如果它可以连接(启用了 OUTPUT),那么它可以写入它们并且要确认复制,它需要 INPUT 访问。

所以 INPUT 和 OUTPUT 也应该在这里。

经纪人 29092 在这里就像没有一样好。使系统处于不可恢复的状态!

标签: apache-kafkadistributed-computing

解决方案


通过了解 Kafka 如何利用 zookeeper 原语来维护和组织集群状态,您的问题可能得到最好的回答。

在 Kafka 中,领导选举是由充当控制器的代理之一精心策划的。只有一个控制器,它是在使用 zookeeper 的代理中选举出来的。

现在,每个代理都将自己注册为 zookeeper 中的“临时节点”。因此,发起 zK 会话的代理通过使用周期性心跳(zK 术语中的滴答声)来维护成员资格。如果代理未能在超时间隔内滴答作响,zookeeper 将删除该节点,并且已注册自己以收到该事件通知的 Kafka 控制器(通过zK watch)得到通知。如果失败的代理是分区的领导者,这将触发新的领导者选举。控制器处理领导者选举并通知所有代理。

所以是的,Kafka 和 zK 之间有 2 路通信——但就分区领导选举而言,这并不是每个代理和 zK 之间的直接 2 路通信。在控制器的方式中有一个中间人。

在您的测试中,由于控制器永远不会收到代理 2 故障的通知,因此代理仍然是分区 1 的领导者。

现在开始,我在猜测

已阻止输入的代理 2 无法接收元数据更新,因此它通过将 ISR 缩小到自身来隔离自己。这也可能有帮助


推荐阅读