了解适用于Java的Kafka Consumer API

时间:2015-12-07 03:04:38

标签: java apache-kafka kafka-consumer-api

我想了解Kafka Receiving API。我已经包含了一个有效的示例代码。

  1. 为什么单个主题的Kafka consumerStreamMap.get(主题)有一个KafkaStream<>列表接收者?
  2. 当前进程似乎遍历KafkaStream<>列出,然后遍历消息。但KafkaReceiver应该永远运行,所以我希望内心永远循环。这使List>多余的。
  3. 一些示例还使用了consumerStreamMap.get(topic).get(0)。这是编写制作人的正确方法吗?

        Map<String, Integer> topicMap = new HashMap<String, Integer>();
        // Define single thread for topic
        topicMap.put(topicName, new Integer(1));
        Map<String, List<KafkaStream<byte[], byte[]>>> consumerStreamsMap = consumer.createMessageStreams(topicMap);
        List<KafkaStream<byte[], byte[]>> streamList = consumerStreamsMap.get(topic);
    
        for (final KafkaStream<byte[], byte[]> stream : streamList) 
        {
           ConsumerIterator<byte[], byte[]> consumerIte = stream.iterator();
           while (consumerIte.hasNext()) 
           {
              counter++;
              String message = new String(consumerIte.next().message());
              String id = topic.hashCode() + "-" + date.getTime() + "-" + counter;
              System.out.println(message);
            }
          }
    

1 个答案:

答案 0 :(得分:3)

您可以在kafka wiki中找到答案: https://cwiki.apache.org/confluence/display/KAFKA/Consumer+Group+Example

  1. consumerStreamMap是(主题,KafkaStream列表)对的映射。流的数量取决于代码中的以下行:

    topicMap.put(topicName, numberOfStreams);
    
  2.   

    如果你提供的线程多于主题上的分区,   一些线程永远不会看到消息。   如果你有更多的分区   你有线程,一些线程将从多个线程接收数据   分区。   如果每个线程有多个分区,则为NO   保证您收到消息的顺序,而不是内部消息   分区偏移量将是连续的。   例如,你可以   从分区10接收来自分区10和6的5条消息,然后接收5条消息   更多来自分区10,然后是5分区,即使是   分区11有可用的数据。   添加更多进程/线程将   导致Kafka重新平衡,可能改变a的分配   分区到线程。

    1. 您需要在自己的线程中迭代每个流。

      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(a_numThreads);
      
          // now create an object to consume the messages
          //
          int threadNumber = 0;
          for (final KafkaStream stream : streams) {
              executor.submit(new ConsumerTest(stream, threadNumber));
              threadNumber++;
          }
      }
      
      public class ConsumerTest implements Runnable {
          private KafkaStream m_stream;
          private int m_threadNumber;
      
          public ConsumerTest(KafkaStream a_stream, int a_threadNumber) {
              m_threadNumber = a_threadNumber;
              m_stream = a_stream;
          }
      
          public void run() {
              ConsumerIterator<byte[], byte[]> it = m_stream.iterator();
              while (it.hasNext())
                  System.out.println("Thread " + m_threadNumber + ": " + new      String(it.next().message()));
              System.out.println("Shutting down Thread: " + m_threadNumber);
          }
      }
      
    2. consumerStreamMap.get(topic).get(0)仅在您有1个主题和1个流时才正确