我需要在多个线程中使用Kafka分区中的记录,并在每个线程上使用唯一记录进行处理。 我有以下代码,我不知道出了什么问题
public class ConsumerThread implements Runnable {
public String name;
public ConsumerThread(String name){
this.name = name;
}
public Properties getDefaultProperty(){
Properties prop = new Properties();
prop.setProperty("group.id", "4");
prop.put("enable.auto.commit", "false");
prop.put("auto.offset.reset", "earliest");
prop.setProperty("bootstrap.servers", "localhost:9092");
prop.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
prop.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
prop.setProperty("max.poll.records","150");
return prop;
}
public void run() {
TopicPartition tp = new TopicPartition("my.topic", 0);
KafkaConsumer consumer = new KafkaConsumer(getDefaultProperty());
ArrayList tpList = new ArrayList<TopicPartition>();
tpList.add(tp);
consumer.assign(tpList);
ConsumerRecords poll = consumer.poll(1000);
Iterator it = poll.iterator();
consumer.commitAsync();
while(it.hasNext()){
ConsumerRecord cr = (ConsumerRecord) it.next();
System.out.println("From "+this.name+" : "+cr.value());
}
consumer.close();
System.out.println("Thread Exiting "+this.name);
}
}
结果
From Thread1 : produced_0
From Thread1 : produced_1
From Thread1 : produced_2
From Thread1 : produced_3
.
.
.
From Thread1 : produced_136
From Thread2 : produced_0
From Thread2 : produced_1
From Thread2 : produced_2
From Thread2 : produced_3
.
.
.
预期:
From Thread1 : produced_0
From Thread1 : produced_1
From Thread1 : produced_2
From Thread1 : produced_3
.
.
.
From Thread1 : produced_136
From Thread2 : produced_4
From Thread2 : produced_5
From Thread2 : produced_6
From Thread2 : produced_137
答案 0 :(得分:0)
只有使用kafka使用者的subscribe方法才能将分区自动分配给使用者组。
但是,您将assign
与特定的主题分区一起使用,因此您承担了将特定的分区分配给不同使用者的责任(但是您始终使用相同的分区0
,因此所有使用者都使用同一主题分区)
答案 1 :(得分:0)
就像Lior Chaga在他的评论中所说,您正在手动为您的消费者分配主题分区。这不是推荐的方法。最重要的是,似乎所有使用者都使用相同的完全相同的groupID。在这种配置下,如果消耗两个线程,则至少有一个使用方收到一条特定的消息,则其他线程中的 none 都不会得到该消息。如果您希望所有使用者线程都彼此拥有自己的“消息”集,而又不会互相干扰,则需要给它们提供不同的group.id
。
要订阅某个主题,以便该主题可以为您处理自动平衡然后消费,您应该执行以下操作(摘自下面链接的KafkaConsumer javadoc):
consumer.subscribe(Arrays.asList("foo", "bar"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records)
System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}
官方的Kafka javadocs有更多详细的解释: https://kafka.apache.org/20/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html