Java 卡夫卡消费者:主题控制阅读

Java 卡夫卡消费者:主题控制阅读,java,apache-kafka,kafka-consumer-api,bigdata,Java,Apache Kafka,Kafka Consumer Api,Bigdata,我有下面的卡夫卡消费代码,其中3个线程正在读取具有3个分区的卡夫卡主题 有没有办法,只有在线程当前正在处理的消息得到处理之后,才会从卡夫卡主题中读取新消息 例如,假设主题中有100条消息,那么是否有任何方法一次只读取和处理3条消息。现在,当处理这3条消息时,只应读取下3条消息,依此类推 public void run(int a_numThreads) { Map<String, Integer> topicCountMap = new HashMap<String, Inte

我有下面的卡夫卡消费代码,其中3个线程正在读取具有3个分区的卡夫卡主题

有没有办法,只有在线程当前正在处理的消息得到处理之后,才会从卡夫卡主题中读取新消息

例如,假设主题中有100条消息,那么是否有任何方法一次只读取和处理3条消息。现在,当处理这3条消息时,只应读取下3条消息,依此类推

public void run(int a_numThreads) {
Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
topicCountMap.put(topic, new Integer(a_numThreads));
Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap = consumer.createMessageStreams(topicCountMap);
List<KafkaStream<byte[], byte[]>> streams = consumerMap.get(topic);

// now launch all the threads
//
executor = Executors.newFixedThreadPool(3);

// now create an object to consume the messages
//
int threadNumber = 0;
for (final KafkaStream stream : streams) {
    executor.submit(new ConsumerTest(stream, threadNumber));
    threadNumber++;
   }
}
public void运行(int a_numThreads){
Map topicCountMap=新HashMap();
put(主题,新整数(a_numThreads));
Map consumerMap=consumer.createMessageStreams(topicCountMap);
列表流=consumerMap.get(主题);
//现在启动所有线程
//
executor=Executors.newFixedThreadPool(3);
//现在创建一个对象来使用消息
//
int threadNumber=0;
对于(最终卡夫卡斯特雷姆流:流){
提交(新的ConsumerTest(流、线程号));
threadNumber++;
}
}

嗯,默认情况下,消费者彼此不了解,因此他们无法“同步”他们的工作。你可以将你的三条信息包装成一条(从而保证它们都会被依次回答),或者引入更多的(“子”)主题

另一种可能性(如果您确实需要保证您的三条消息将被单个消费者使用)可能是您的所有消费者同步他们的工作,或者通知跟踪您工作的控制器


但感觉你“做错了”,实际上队列中的消息是无状态的,只有它们在主题中的顺序决定了它们的“处理顺序”。处理消息的时间应该无关紧要。

如果ConsumerTest中的迭代器正在同步处理消息,则一次仅消耗3条消息。默认情况下,enable.auto.commit为true。确保没有将其设置为false,否则需要添加提交偏移量的逻辑

前-

ConsumerIterator streamIterator=stream.iterator();
while(streamIterator.hasNext()){
String kafkaMsg=新字符串(streamIterator.next().message());
} 

你好,尼古拉斯,我不关心邮件的顺序。我想要的是在某一点上只从主题中读取N条消息,然后当这N条消息的所有处理完成后,只提取接下来的N条消息。啊,在这种情况下,seek(TopicPartition,long offset)可能会起作用?但您必须意识到,如果“在错误的时间”请求偏移量,可能会丢失数据。但是,您可以获取所有数据,只读取N条消息并丢弃其余的消息。然后用新的偏移量+N再次触发队列?这是一个非常好的方法。到目前为止,它在meAlso中工作良好,使用者必须在本地存储每个分区最后消耗的偏移量。否则,它可能会丢失上次使用的偏移量的标记;像这样。如果这是正确的吗?是的,这是正确的。需要注意的一点是,这将每隔1秒提交一次偏移量。如果您的服务崩溃,那么在这1秒间隔中处理的所有消息将不会被提交,并且当您的消费者再次旋转时将被重新处理(在设计服务时要考虑边缘情况)。因此,您需要确保您的使用者逻辑对服务崩溃和重复消息处理具有容错性。
 ConsumerIterator<byte[], byte[]> streamIterator= stream.iterator(); 
 while (streamIterator.hasNext()) { 
   String kafkaMsg= new String(streamIterator.next().message()); 
 }