向卡夫卡提交问题

时间:2018-06-14 21:02:24

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

我正在研究一个模块,要求是有一个生产者,我们正在使用kafka作为数据生成队列并将其提供给消费者。

现在在消费者中,我正在尝试实施至少一次消息传递方案。

为此,我必须汇集来自kafka的消息,然后消费者那些消费者。消费后我正在调用consumer.commitAsync(offset,Callback)。

我想知道会发生什么

案例1)。当从不调用commitAsync()api时(假设在调用此api之前有一个异常)。在我的情况下,我假设消息将再次被泵送到消费者;但它没有发生。消费者再也没有得到那些数据了。

案例2)。如果消费者重新启动。

以下是使用消费者设置的属性的代码段

private Properties getConsumerProperties() {
        final Properties props = new Properties();
        props.put(BOOTSTRAP_SERVERS_CONFIG, "server");
        props.put(GROUP_ID_CONFIG, "groupName");
        props.put(ENABLE_AUTO_COMMIT_CONFIG, false);
        props.put(HEARTBEAT_INTERVAL_MS_CONFIG, heartBeatinterval);
        props.put(METADATA_MAX_AGE_CONFIG, metaDataMaxAge);
        props.put(SESSION_TIMEOUT_MS_CONFIG, sessionTimeout);
        props.put(AUTO_OFFSET_RESET_CONFIG, autoOffsetReset);
        props.put(KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        props.put(VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        return props;
    }

现在在消费者中,基于一些属性集;我有3个主题,每个主题创建3个消费者(因为有3个分区和3个kafka经纪人)。

对于数据的消费......我在收到fron kafka时将某个属性识别为数据包并将其传递给相关主题(我为不同的主题采用了不同的线程池并在此基础上创建任务包中的属性并提交给线程池)。在任务中,处理后我调用了consumer.commitAsync(offset,callback)。

我希望在没有为某些数据包调用commitAsync的情况下再次从kafka中提取相同的消息...但令我惊讶的是它没有回来......我错过了什么。是否有任何类型的设置我们需要在apache-kafka以及At-Least-One中进行设置。

请建议。

1 个答案:

答案 0 :(得分:0)

您的问题中有几件事需要解决。

在我得到关于如何实现至少一次行为的建议之前,我会尝试解决2个案例

  

案例1)。什么时候从不调用commitAsync()api(假设有一个   在调用这个api之前的异常。)在我的情况下,我假设了   消息将再次被消费给消费者;但事实并非如此   发生了。消费者再也没有得到那些数据了。

您的消费者无法获取旧数据的原因可能是enable.auto.commit属性,默认设置为true,并会在后台定期提交偏移量。因此,后续运行中的消费者将找到可以使用的偏移量,并且只等待新数据/消息到达。

  

案例2)。如果消费者重新启动。

这也是类似的,即如果重新启动后的消费者发现要使用的提交偏移量,它将从该偏移开始消耗是否由于enable.auto.commit属性设置为{{1}而自动提交了偏移量或者明确地调用true

现在,转到关于如何实现至少一次行为的部分 - 我可以想到以下两种方式

  1. 如果要控制提交偏移量,请将“enable.auto.commit”属性设置为commitAsync()/commitSync(),然后在回调中处理重试时调用falsecommitSync()功能
  2. 注意:同步和异步提交的选择取决于您的延迟预算和任何其他要求。所以,这里不要过多介绍这些细节。

    1. 另一种选择是利用自动偏移提交功能,即将commitAsync()设置为enable.auto.committrue为可接受的数字(同样,根据您对自己喜欢的频率的要求)提交抵消)。
    2. 我认为Kafka的默认行为是以至少一次的语义为中心,因此它应该相当简单。

      我希望这有帮助!