问题
具有特定组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分钟以上。我做错了什么?
我的环境
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);
}
}
答案 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);
}
}