我正在使用只有一个消费者的消费者群体,只有一个经纪人(docker wurstmeister图像)。在代码中决定是否提交偏移量 - 如果代码返回错误,则不提交消息。我需要确保系统不会丢失任何消息 - 即使这意味着永远重试相同的消息(现在;))。为了测试这个,我创建了一个简单的处理程序,它不会在'error'字符串发送为kafka的消息时提交偏移量。所有其他字符串都被提交。
kafka-console-producer --broker-list localhost:9092 --topic test
>this will be commited
正在运行
kafka-run-class kafka.admin.ConsumerGroupCommand --bootstrap-server localhost:9092 --group michalgrupa --describe
返回
TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID
test 0 13 13 0
所以没关系,没有滞后。现在我们传递'error'字符串来假装发生了一些不好的事情并且没有提交消息:
TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID
test 0 13 14 1
当前偏移量保持在正确位置+有1个滞后消息。现在,如果我们再次传递正确的消息,则偏移将继续到15:
TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
test 0 15 15
并且不会再次拾取第14号消息。这是默认行为吗?我是否需要手动跟踪上次偏移并加载消息+ 1?我已将提交间隔设置为0,希望不使用任何auto.commit机制。
获取/提交代码:
go func() {
for {
ctx := context.Background()
m, err := mr.brokerReader.FetchMessage(ctx)
if err != nil {
break
}
if err := msgFunc(m); err != nil {
log.Errorf("# messaging # cannot commit a message: %v", err)
continue
}
// commit message if no error
if err := mr.brokerReader.CommitMessages(ctx, m); err != nil {
// should we do something else to just logging not committed message?
log.Errorf("cannot commit message [%s] %v/%v: %s = %s; with error: %v", m.Topic, m.Partition, m.Offset, string(m.Key), string(m.Value), err)
}
}
}()
读者配置:
kafkaReader := kafka.NewReader(kafka.ReaderConfig{
Brokers: brokers,
GroupID: groupID,
Topic: topic,
CommitInterval: 0,
MinBytes: 10e3,
MaxBytes: 10e6,
})
答案 0 :(得分:1)
在kafka中,您只需提交偏移量而不是单个消息。如果我理解你的代码是正确的(不是go-developer)。您只需在收到无效邮件后继续操作。如果在无效消息之后出现有效消息,您将再次提交偏移量 - 我猜这不是您的意图。
只是要明确提交或提交偏移量的含义:您的消费者群体将偏移量存储到专用的内部kafka主题(或者在zookeeper上的旧版kafka版本上)。偏移可以标识主题中的单个位置(或者更精确地标识给定主题的分区)。这意味着您只能以线性方式使用主题。
在这里你可以看到kafka-consumer方面会发生什么:
您正在使用(很可能是多个)堆栈消息。您在此主题/分区提交位置(a.k.a偏移量)。所以你可以不说我想再次重新创建一个特定的消息。您可以做的是在点击无效消息后停止消费。在这种情况下,您的问题将是:我如何摆脱此消息。从kafka主题中删除单个消息很棘手。一种常见的模式是将此消息写入某种死信主题,并与不同的消费者一起处理。
希望你能让事情变得更加清晰。
答案 1 :(得分:0)
您的Kafka使用者似乎已设置为自动提交偏移量(这是默认设置)。
如果是这样,这可能就是您的应用跳过错误消息的原因-尽管您跳过了CommitMessages
调用,但提交是在后台线程上执行的
请在文档中查看enable.auto.commit
的属性规范:https://kafka.apache.org/documentation/#newconsumerconfigs
答案 2 :(得分:0)
在这里有必要了解消费者补偿的概念。对于正在运行的使用者应用程序,它将消费消息的偏移量存储在内存中,而与提交/取消提交偏移量无关,如果重新启动使用者应用程序,它将检索“ CURRENT-OFFSET”的偏移量以继续使用。