Apache Kafka Java使用者未收到复制因子大于1的主题的消息
我从ApacheKakfa开始,用Java开发了一个简单的生产者、消费者应用程序。我正在使用Apache Kafka Java使用者未收到复制因子大于1的主题的消息,java,apache-kafka,Java,Apache Kafka,我从ApacheKakfa开始,用Java开发了一个简单的生产者、消费者应用程序。我正在使用kafka客户端version0.10.0.1并在Mac上运行它 我创建了一个名为replicated\u topic\u partitioned的主题,有3个分区,复制因子为3 我在2181号港口启动了动物园管理员。我分别在端口9092、9093和9094上启动了三个id为1、2和3的代理 下面是descripe命令的输出 kafka_2.12-2.3.0/bin/kafka-topics.sh --d
kafka客户端
version0.10.0.1
并在Mac上运行它
我创建了一个名为replicated\u topic\u partitioned
的主题,有3个分区,复制因子为3
我在2181号港口启动了动物园管理员。我分别在端口9092、9093和9094上启动了三个id为1、2和3的代理
下面是descripe命令的输出
kafka_2.12-2.3.0/bin/kafka-topics.sh --describe --topic replicated_topic_partitioned --bootstrap-server localhost:9092
Topic:replicated_topic_partitioned PartitionCount:3 ReplicationFactor:3 Configs:segment.bytes=1073741824
Topic: replicated_topic_partitioned Partition: 0 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2
Topic: replicated_topic_partitioned Partition: 1 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
Topic: replicated_topic_partitioned Partition: 2 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
我写了一个简单的生产者和消费者代码。生产者成功运行并发布了消息。但当我启动消费者时,轮询调用只是无限期地等待。在调试时,我发现它在ConsumerNetworkClient上的waitMetadataUpdate方法上继续循环
以下是生产者和消费者的代码
Properties properties = new Properties();
properties.put("bootstrap.servers", "localhost:9092");
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> myProducer = new KafkaProducer<>(properties);
DateFormat dtFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
String topic = "replicated_topic_partitioned";
int numberOfRecords = 10;
try {
for (int i = 0; i < numberOfRecords; i++) {
String message = String.format("Message: %s sent at %s", Integer.toString(i), dtFormat.format(new Date()));
System.out.println("Sending " + message);
myProducer.send(new ProducerRecord<String, String>(topic, message));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
myProducer.close();
}
其他两个代理的server.properties是上述代理的副本,其broker.id、端口和log.dirs已更改
这对我不起作用:
但是,如果我从传递分区的命令行启动使用者,它将成功读取该分区的消息。但当只指定了一个主题时,它不会收到任何消息 作品:
kafka_2.12-2.3.0/bin/kafka-console-consumer.sh --topic replicated_topic_partitioned --bootstrap-server localhost:9092
--from-beginning --partition 1
不起作用:
kafka_2.12-2.3.0/bin/kafka-console-consumer.sh --topic replicated_topic_partitioned --bootstrap-server localhost:9092
--from-beginning
注意:对于复制因子等于1的主题,上述使用者非常适合
问题:
myConsumer.assign(Collections.singletonList)(新主题分区(主题,2)
)因此,您发送了10条记录,但所有10条记录都具有相同的密钥:
for (int i = 0; i < numberOfRecords; i++) {
String message = String.format("Message: %s sent at %s", Integer.toString(i), dtFormat.format(new Date()));
System.out.println("Sending " + message);
myProducer.send(new ProducerRecord<String, String>(topic, message)); <--- KEY=topic
}
for(int i=0;i myProducer.send(新产品记录(主题、消息));免责声明:这不是答案
Java使用者现在正在按预期工作。我没有对代码或配置做任何更改。我所做的唯一一件事就是重新启动Mac。这导致kafka logs
文件夹(我猜也是zookeeper
文件夹)被删除
我重新创建了主题(使用相同的命令-3个分区,复制系数为3)。然后使用相同的配置-noadvised.host.name
或advised.port
config重新启动代理
所以,对卡夫卡日志和主题的再创造弥补了早些时候引起问题的一些东西
我唯一的嫌疑犯是一个未正确终止的使用者。我运行消费者代码时,最初没有在finally块中调用消费者的close
。我也有相同的group.id
。可能所有3个分区都分配给了未正确终止或关闭的使用者。这只是一个猜测
但是,即使调用myConsumer.position(new-TopicPartition(topic,2))
之前我将使用者分配到一个分区时,它也没有返回响应。它在相同的waitingmetadataupdate
方法中循环。“但是当只指定了一个主题时,它不起作用。”-By“不起作用”你是什么意思?它失败了吗?@giorgosmyriantous它没有收到任何消息。更新了我的问题,澄清了这一点。你知道每个分区有多少消息吗?@giorgosmyriantous我总共发送了10条消息。它们被分发到了分区中-我是在通过-partit时通过控制台使用者输出说的ion
0,1和2。为什么每个分区的消息数在这里有什么意义?如何知道生成成功?检查返回的未来?是否提供回调?是否调用flush()在生成器上?我想这不可能是真的。在内部,当我不传递密钥时,它默认为null
。在这种情况下,它应该使用循环。此外,当我通过传递主题和分区来运行控制台生成器时,它会检索所有分区(0、1和2)的消息。我的问题是Java使用者没有检索消息。重新启动后,该问题现在没有发生。它一定与删除和重新创建卡夫卡日志有关。
。请参阅我的答案(不是真正的答案)
kafka_2.12-2.3.0/bin/kafka-console-consumer.sh --topic replicated_topic_partitioned --bootstrap-server localhost:9092
--from-beginning
for (int i = 0; i < numberOfRecords; i++) {
String message = String.format("Message: %s sent at %s", Integer.toString(i), dtFormat.format(new Date()));
System.out.println("Sending " + message);
myProducer.send(new ProducerRecord<String, String>(topic, message)); <--- KEY=topic
}