昨天,我从日志中发现,在Kafka小组协调员发起小组重新平衡之后,kafka正在重用一些消息。这些消息已于两天前消耗掉(已从日志中确认)。
日志中还报告了另外两个重新平衡,但是它们不再重新使用消息。那么,为什么第一次重新平衡会导致重复使用消息?有什么问题?
我正在使用golang kafka客户端。这是代码
config := sarama.NewConfig()
config.Version = version
config.Consumer.Offsets.Initial = sarama.OffsetOldest
并且我们在声明消息之前正在处理邮件,因此似乎我们对kafka使用了“最少发送一次”策略。一台机器上有三个代理,而另一台机器上只有一个使用者线程(执行例程)。
对此现象有任何解释吗? 我认为消息一定是已经提交的,因为它们是两天前被消耗掉的,还是为什么kafka会在不提交消息的情况下保持两天以上的偏移量?
消费代码示例:
func (consumer *Consumer) ConsumeClaim(session
sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
for message := range claim.Messages() {
realHanlder(message) // consumed data here
session.MarkMessage(message, "") // mark offset
}
return nil
}
已添加:
重新启动应用后发生了重新平衡。还有另外两次重启没有引起重新使用
kafka的配置
log.retention.check.interval.ms = 300000
log.retention.hours = 168
zookeeper.connection.timeout.ms = 6000
group.initial.rebalance.delay.ms = 0
delete.topic.enable = true
auto.create.topics.enable = false
答案 0 :(得分:0)
通过阅读golang saram客户端和kafka服务器的源代码,终于找到了以下原因
消费者组补偿保留时间为 24小时,这是kafka的默认设置,而 log 保留时间为我们明确设定的7天。
我的服务器应用程序在很少有人可以访问的测试环境中运行,这意味着kafka生产者可能生成的消息很少,然后消费者组几乎没有消息可以消费,因此消费者可能没有提交任何消息长时间抵消。
当消耗偏移量未更新超过24小时时,由于偏移量配置,kafka代理/协调器将从分区中删除消耗量偏移量。下次saram从kafka代理查询偏移量在哪里时,客户端当然什么也没得到。请注意,我们使用的是 sarama.OffsetOldest 作为初始值,然后sarama客户端将从kafka代理保存的消息开始处消耗消息,这导致消息被重用,这很可能发生,因为日志保留 7天