如果消耗时间短,Kafka不会保存偏移量

时间:2018-11-23 10:10:46

标签: php apache-kafka

问题

具有特定组ID的消费者连接到代理,侦听主题少于1分钟并断开连接(根据业务逻辑)。在收听主题时,它可能会消耗一些消息。 当同一使用者重复此操作时,它会消耗相同的消息!

我发现Kafka以1分钟的间隔保存偏移量。这意味着消费者必须收听该主题超过1分钟。 如何缩短此间隔?

我发现了这样的属性:

  • log.flush.offset.checkpoint.interval.ms
  • log.flush.start.offset.checkpoint.interval.ms
  • offset.flush.interval.ms-看起来最合适

我尝试将它们设置在server.properties文件中:

log.flush.offset.checkpoint.interval.ms=6000
log.flush.start.offset.checkpoint.interval.ms=6000
offset.flush.interval.ms=6000

重新启动Kafka和Zookeeper。但这没有帮助。消费者仍然必须收听该主题1分钟以上。我做错了什么?

我的环境

  • Kafka和Zookeeper通过Confluent。
  • php-rdkafka作为客户端库
  • enable.auto.commit设置为true

我使用低级消费者。 auto.offset.reset设置为smallest。 代码示例

<?php
$topicConf = new \RdKafka\TopicConf();
$topicConf->set('auto.offset.reset', 'smallest');

$conf = new \RdKafka\Conf();
$conf->set('group.id', 'foo');

$kafkaConsumer = new \RdKafka\Consumer($conf);
$kafkaConsumer->addBrokers('queue.a:9092');
$kafkaConsumer->setLogLevel(LOG_DEBUG);

$topicConf = new \RdKafka\TopicConf();
$topicConf->set('auto.offset.reset', 'smallest');

$queue = $kafkaConsumer->newQueue();
$topic = $kafkaConsumer->newTopic('topic_name', $topicConf);
$topic->consumeQueueStart(0, \RD_KAFKA_OFFSET_STORED, $queue);

while (true) {
    $msg = $queue->consume(2000);
    if ($msg !== null) {
        var_dump($msg);
    }
}

1 个答案:

答案 0 :(得分:1)

您应尝试在使用者中明确提交偏移量:

  

向消费者明确提出补偿   如果您使用自动偏移量提交,则无需担心显式地提交偏移量。但是,如果您决定需要对偏移提交的时间进行更多控制,您确实需要考虑如何提交偏移量-为了最大程度地减少重复,或者因为您在主要使用者轮询循环之外进行事件处理。

Kafka definitive guide,第127页中提取。(您可以下载免费的电子书)

建议您在处理事件后始终提交偏移量。如果您在轮询循环中进行了所有处理,并且不维护轮询循环之间的状态(例如,用于聚合),则应该放轻松。您可以在轮询循环结束时使用自动提交配置或提交事件。

我自己还没有使用过php客户端,但是看起来像this could be what you need

在上面的代码示例中添加

while (true) {
    $msg = $queue->consume(2000);
    if ($msg !== null) {
        var_dump($msg);
        $kafkaConsumer->commit($msg);
    }
}