如何处理具有 2 个分区和 2 个副本的主题的两个节点的 kafka 领导者故障转移?

How to handle kafka leader failover with two nodes for a topic with 2 partitions and 2 replicas?

我正在多节点环境中使用 kafka 来测试故障转移的工作原理。 实际上,我有 2 个 VM,每个 VM 内有 1 个 kafka 节点,两个 VM 之一内只有 1 个 zookeeper。我知道没有最佳的生产配置,但只是为了锻炼自己,更好地理解事物。

这是我的配置: VM1 ip : 192.168.64.2 (With only one broker with broker.id=2) VM2 ip : 192.168.64.3 (Zookeeper 运行 这里是 broker broker.id=1)

我是通过podman启动kafka的(这个不是podman的问题,一切都配置好了)

在 VM1 上:

podman run -e KAFKA_BROKER_ID=2 -e KAFKA_ZOOKEEPER_CONNECT=192.168.64.3:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9093,PLAINTEXT_HOST://192.168.64.2:29092 -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=2 -e KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT_HOST -e UNCLEAN_LEADER_ELECTION_ENABLE=true --pod zookeeper-kafka confluentinc/cp-kafka:latest

在 VM2 上:

podman run -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT=localhost:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092,PLAINTEXT_HOST://192.168.64.3:29092 -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=2 -e KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT_HOST -e UNCLEAN_LEADER_ELECTION_ENABLE=true  --pod zookeeper-kafka confluentinc/cp-kafka:latest

现在我创建一个主题“订单”:

./kafktopics --create --bootstrap-server 192.168.64.2:29092,192.168.64.3:29092 --replication-factor 2 --partitions 2 --topic orders

然后我创建一个生产者:

./kafkconsole-producer --broker-list 192.168.64.2:29092,192.168.64.3:29092 --topic orders

还有一个消费者:

./kafka-console-consumer --bootstrap-server 192.168.64.2:29092,192.168.64.3:29092 --topic orders```

这是我正在尝试做的事情:

  1. 启动Zookeeper,2个kafka节点,创建“order”主题,生产者和消费者(OK,一切正常)
  2. 在我的生产者中发送消息并检查消费者是否收到它(确定)
  3. 杀死 VM2 上的 kafka 节点(确定)
  4. 在我的生产者中再次发送一条消息并检查消费者是否收到它(好的,VM1 上的代理可以分发消息)
  5. 在 VM2 上重启被杀死的 kafka 节点(好的。之后我可以看到 2 个分区以 VM1 作为领导者)
  6. 在我的生产者中再次发送消息并检查消费者接收 ID(确定)
  7. 杀死 VM1 上的 kafka 节点,它现在是 2 个分区的领导者(确定)
  8. 在我的生产者中再次发送一条消息并检查消费者是否收到它(好的,VM2 上的代理可以分发消息)
  9. 在 VM1 上重启被杀死的 kafka 节点(好的。之后我可以看到 2 个分区以 VM2 作为领导者)
  10. 在我的生产者中再次发送一条消息并检查消费者是否收到它(确定)
  11. 再次杀死VM2上的kafka节点(OK)
  12. 在我的生产者中再次发送一条消息并检查消费者是否收到它(不正常): 在这里,生产者无法发送消息,而我的消费者永远不会收到消息! 一段时间后,我的生产者出现错误:
ERROR Error when sending message to topic orders with key: null, value: 9 bytes with error: (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for orders-0:120000 ms has passed since batch creation

我真的不明白这里发生了什么?一开始它运行良好,但在 start/stop/start broker 之后,它开始失败了!我需要明确一点,我从来没有同时杀死 2 个经纪人。

你能解释一下我在这里缺少什么吗?

谢谢大家:)


编辑

要完成以下评论:

@OneCricketeer,我把你评论的答案放在这里。

启动时,一切正常时:

Topic: orders   TopicId: I3hMNln9TpSuo76xHSpMXQ PartitionCount: 2   ReplicationFactor: 2    Configs:
    Topic: orders   Partition: 0    Leader: 2   Replicas: 2,1   Isr: 2,1
    Topic: orders   Partition: 1    Leader: 1   Replicas: 1,2   Isr: 1,2

杀死 VM2 后:

Topic: orders   TopicId: I3hMNln9TpSuo76xHSpMXQ PartitionCount: 2   ReplicationFactor: 2    Configs:
    Topic: orders   Partition: 0    Leader: 2   Replicas: 2,1   Isr: 2
    Topic: orders   Partition: 1    Leader: 2   Replicas: 1,2   Isr: 2

杀死 VM1 后:

Topic: orders   TopicId: I3hMNln9TpSuo76xHSpMXQ PartitionCount: 2   ReplicationFactor: 2    Configs:
    Topic: orders   Partition: 0    Leader: 1   Replicas: 2,1   Isr: 1
    Topic: orders   Partition: 1    Leader: 1   Replicas: 1,2   Isr: 1

杀死 VM2 后:

Topic: orders   TopicId: I3hMNln9TpSuo76xHSpMXQ PartitionCount: 2   ReplicationFactor: 2    Configs:
    Topic: orders   Partition: 0    Leader: 2   Replicas: 2,1   Isr: 2
    Topic: orders   Partition: 1    Leader: 2   Replicas: 1,2   Isr: 2

(从这里开始,生产者不能再发布消息了)

经过很长时间的阅读和调查关于kafka的东西,我终于找到了问题的答案。

只有2个经纪人,我需要以下配置

KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=2
KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS=1

问题是偏移主题的默认分区数。 (如果我没记错的话,是 50 个中的 49 个)。

现在只有一个分区和 2 个副本,一切正常,我可以 start/stop/start/stop/.... 我的经纪人想多少次都可以,另一个经纪人带头继续处理我的消息。

希望对以后的人有所帮助。