如何处理具有 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```
这是我正在尝试做的事情:
- 启动Zookeeper,2个kafka节点,创建“order”主题,生产者和消费者(OK,一切正常)
- 在我的生产者中发送消息并检查消费者是否收到它(确定)
- 杀死 VM2 上的 kafka 节点(确定)
- 在我的生产者中再次发送一条消息并检查消费者是否收到它(好的,VM1 上的代理可以分发消息)
- 在 VM2 上重启被杀死的 kafka 节点(好的。之后我可以看到 2 个分区以 VM1 作为领导者)
- 在我的生产者中再次发送消息并检查消费者接收 ID(确定)
- 杀死 VM1 上的 kafka 节点,它现在是 2 个分区的领导者(确定)
- 在我的生产者中再次发送一条消息并检查消费者是否收到它(好的,VM2 上的代理可以分发消息)
- 在 VM1 上重启被杀死的 kafka 节点(好的。之后我可以看到 2 个分区以 VM2 作为领导者)
- 在我的生产者中再次发送一条消息并检查消费者是否收到它(确定)
- 再次杀死VM2上的kafka节点(OK)
- 在我的生产者中再次发送一条消息并检查消费者是否收到它(不正常):
在这里,生产者无法发送消息,而我的消费者永远不会收到消息!
一段时间后,我的生产者出现错误:
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/.... 我的经纪人想多少次都可以,另一个经纪人带头继续处理我的消息。
希望对以后的人有所帮助。
我正在多节点环境中使用 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```
这是我正在尝试做的事情:
- 启动Zookeeper,2个kafka节点,创建“order”主题,生产者和消费者(OK,一切正常)
- 在我的生产者中发送消息并检查消费者是否收到它(确定)
- 杀死 VM2 上的 kafka 节点(确定)
- 在我的生产者中再次发送一条消息并检查消费者是否收到它(好的,VM1 上的代理可以分发消息)
- 在 VM2 上重启被杀死的 kafka 节点(好的。之后我可以看到 2 个分区以 VM1 作为领导者)
- 在我的生产者中再次发送消息并检查消费者接收 ID(确定)
- 杀死 VM1 上的 kafka 节点,它现在是 2 个分区的领导者(确定)
- 在我的生产者中再次发送一条消息并检查消费者是否收到它(好的,VM2 上的代理可以分发消息)
- 在 VM1 上重启被杀死的 kafka 节点(好的。之后我可以看到 2 个分区以 VM2 作为领导者)
- 在我的生产者中再次发送一条消息并检查消费者是否收到它(确定)
- 再次杀死VM2上的kafka节点(OK)
- 在我的生产者中再次发送一条消息并检查消费者是否收到它(不正常): 在这里,生产者无法发送消息,而我的消费者永远不会收到消息! 一段时间后,我的生产者出现错误:
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/.... 我的经纪人想多少次都可以,另一个经纪人带头继续处理我的消息。
希望对以后的人有所帮助。