kafka 0.90消费者持续组间运行

时间:2016-05-23 15:06:49

标签: apache-kafka kafka-consumer-api

我建立了以下kafka消费者:

Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:6667");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "TEST1");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringDeserializer");
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringDeserializer");
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "10000");
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,"1000");
this.kconsumer = new KafkaConsumer(props);

我希望消费者在这个群体启动时最早开始。所以我第一次运行它,它按预期完美地工作。只要订阅存在且连接未关闭,它就会继续增加偏移量。

当我登录kafka并运行以下内容时:

./kafka-consumer-groups.sh --bootstrap-server localhost:6667 --new-consumer --group TEST1 --describe

我确切地看到了预期的内容,偏移量的增加等。当连接关闭但是运行相同的命令导致"消费者组TEST1不存在或正在重新平衡。&#34 ;只有它没有重新平衡,它就消失了。

当消费者未运行时,如何坚持群体的存在?我在消费者或卡夫卡中错过了配置吗?

另一方面,当我将OFFSET参数改为"最新"除非记录未过期,否则除非加载新记录,否则我根本没有记录。

所以底线,我想要做的是启动一个具有给定名称的新消费者,能够从最早的可用记录中提取,关闭该消费者,如果我再次启动具有该名称的消费者从我离开的地方拉。我缺少什么想法?或者我只是误解了高层消费者的工作方式?

1 个答案:

答案 0 :(得分:1)

如果有人遇到这个并想知道我做了什么。在确定该组是否存在之后,我能够设置偏移量。这样做意味着如果组存在使用“最新”。如果没有,请使用“最早”。

    private void buildConsumer(String offset)
    {
        Properties props = new Properties();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:6667");
        props.put(ConsumerConfig.GROUP_ID_CONFIG, this.groupId);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringDeserializer");
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringDeserializer");
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
        props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "10000");
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, offset);
        props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,"1000");
        this.kconsumer = new KafkaConsumer(props);
    }

    /*
    Check if the group exists before polling.
    If it does, leave with default offset.
    If it does not exists, set the offset to earliest to ensure you are getting all the records
    */
    private void groupExists(String topic)
    {
        TopicPartition toc = new TopicPartition(topic, 0);
        OffsetAndMetadata oam = kconsumer.committed(toc);
        if(oam != null){
            //do nothing, all is well, start from last commit
        } else {
            /*
            when a new group is started the AUTO_OFFSET_RESET_CONFIG
            needs to be set to earliest to ensure all records are picked up
            Since that property can only be set at instantiation the consumer
            must be rebuilt and resubscribed
            */
            buildConsumer("earliest");
            this.kconsumer.subscribe(Arrays.asList(topic));
        }
    }