Kafka Consumer API跳跃偏移

时间:2019-05-10 07:37:16

标签: apache-kafka

我正在使用Kafka 2.0版和Java消费者API来消费主题中的消息。我们使用的是单节点Kafka服务器,每个分区一个使用者。我观察到,消费者正在失去一些信息。 该方案是: 消费者调查主题。 我已经为每个线程创建了一个消费者。 获取消息并将其提供给处理程序以处理消息。 然后,它使用“至少一次” Kafka Consumer语义提交偏移,以提交Kafka偏移。 同时,我还有另一个使用不同组ID的使用者。在这个使用者中,我只是增加消息计数器并提交偏移量。此使用者没有消息丢失。

try {
    //kafkaConsumer.registerTopic();

    consumerThread = new Thread(() -> {
        final String topicName1 = "topic-0";
        final String topicName2 = "topic-1";
        final String topicName3 = "topic-2";
        final String topicName4 = "topic-3";

        String groupId = "group-0";
        final Properties consumerProperties = new Properties();
        consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.13.49:9092");
        consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArrayDeserializer");
        consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArrayDeserializer");
        consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
        consumerProperties.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, "100");
        consumerProperties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
        consumerProperties.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 1000);

        try {
            consumer = new KafkaConsumer<>(consumerProperties);
            consumer.subscribe(Arrays.asList(topicName1, topicName2, topicName3, topicName4));
        } catch (KafkaException ke) {
            logTrace(MODULE, ke);
        }
        while (service.isServiceStateRunning()) {
            ConsumerRecords<String, byte[]> records = consumer.poll(Duration.ofMillis(100));
            for (TopicPartition partition : records.partitions()) {
                List<ConsumerRecord<String, byte[]>> partitionRecords = records.records(partition);
                for (ConsumerRecord<String, byte[]> record : partitionRecords) {
                    processMessage(simpleMessage);

                }
            }
            consumer.commitSync();
        }
        kafkaConsumer.closeResource();
    }, "KAKFA_CONSUMER");

} catch (Exception e) {
}

1 个答案:

答案 0 :(得分:2)

在这里使用subscribe()似乎有问题。

Subscribe用于订阅主题而不是分区。要使用特定的分区,您需要使用assign()。阅读文档摘录:

  

公共无效订阅(java.util.Collection主题)

     订阅给定主题列表以动态分配   分区。主题订阅不是增量订阅。此清单将   替换当前分配(如果有)。这不可能   将主题订阅与组管理和手册结合起来   通过Assign(Collection)进行分区分配。如果给定的清单   topic为空,与unsubscribe()相同。这是一个   subscription(Collection,ConsumerRebalanceListener)的简写,其中   使用noop侦听器。如果您需要寻求特定能力   偏移量,您应该更喜欢subscription(Collection,   ConsumerRebalanceListener),因为组重新平衡会导致   要重置的分区偏移量。您还应该提供自己的   侦听器,如果您正在执行自己的偏移量管理,因为   监听器使您有机会在重新平衡之前提交偏移量   完成。


  

公共无效分配(java.util.Collection分区)

     

手动为此用户分配分区列表。这个介面   不允许增量分配,并将替换   上一个作业(如果有)。如果给定的主题列表   partitions为空,与unsubscribe()相同。手册   通过此方法分配主题不使用使用者的组   管理功能。这样一来,就不会再有平衡   组成员资格或集群和主题时触发操作   元数据更改。请注意,不能同时使用两个手册   使用assign(Collection)进行分区分配,使用a   subscription(Collection,ConsumerRebalanceListener)。