简体   繁体   English

重用Kafka消息的可能原因

[英]Possible Reasons of Reconsuming Kafka Messages

Yesterday I found from log the kafka was reconsuming some messages after the Kafka group coordinator initiated a group rebalance. 昨天我从日志中发现,在Kafka小组协调员发起小组重新平衡之后,kafka正在重用一些消息。 These messages had been consumed two days ago (confirmed from log). 这些消息已于两天前消耗掉(已从日志中确认)。

There were two other rebalancing reported in the log, but they didn't reconsume messages anymore. 日志中还报告了另外两个重新平衡,但是它们不再重新使用消息。 So why the first time reblancing would cause reconsuming messages? 那么,为什么第一次重新平衡会导致重复使用消息? What were the problems? 有什么问题?

I am using the golang kafka client. 我正在使用golang kafka客户端。 here are the code 这是代码

config := sarama.NewConfig()
config.Version = version
config.Consumer.Offsets.Initial = sarama.OffsetOldest 

and we are handling messges before claiming messages, so seems we are using the Send At Least Once strategy for kafka. 而且我们在索取消息之前正在处理邮件,因此似乎我们对kafka使用了“最少发送一次”策略。 We have three brokers in one machine, and only one consumer thread (go routine) in the other machine. 一台机器上有三个代理,而另一台机器上只有一个使用者线程(执行例程)。

Any explanations for this phoenomenon? 对这种现象有什么解释吗? I think the messages must have been committed, coz they were consumed two days ago, or why would kafka keep offsets for more than two days without committing? 我认为这些消息一定已经提交了,因为它们是两天前被消耗掉的,或者为什么kafka会在不提交的情况下将抵消额保持两天以上?

Consuming Code sample: 消费代码示例:

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
}

Added: 添加:

  1. Rebalancing happened after app restarted. 重新启动应用程序后发生重新平衡。 There were two other restarts which didn't cuase reconnsume 还有另外两次重启没有引起重新启动

  2. configs of kafka Kafka的配置

    log.retention.check.interval.ms=300000 log.retention.check.interval.ms = 300000
    log.retention.hours=168 log.retention.hours = 168
    zookeeper.connection.timeout.ms=6000 zookeeper.connection.timeout.ms = 6000
    group.initial.rebalance.delay.ms=0 group.initial.rebalance.delay.ms = 0
    delete.topic.enable = true delete.topic.enable = true
    auto.create.topics.enable=false auto.create.topics.enable = false

By reading the source code of both golang saram client and kafka server, finally I found the reason as below 通过阅读golang saram客户端和kafka服务器的源代码,终于找到了以下原因

  1. Consumer group offset retention time is 24hours , which is a default setting by kafka, while log retention is 7days explicitly set by us. 消费者组补偿的保留时间为24小时 ,这是kafka的默认设置,而日志保留时间是我们明确设置的7天

  2. My server app is running in test environment where few people can visit, which means there may be few messages produced by kafka producer, and then the consumer group has few messages to consumes, thus the consumer may not commit any offset for long time. 我的服务器应用程序运行在很少有人可以访问的测试环境中,这意味着kafka生产者可能会产生很少的消息,然后消费者组几乎没有消息可以消费,因此消费者可能不会长时间提交任何补偿。

  3. When the consume offset is not updated for more than 24hours, due to the offset config, the kafka broker/coordinator will remove the consume offset from partitions. 当消耗偏移量未更新超过24小时时,由于偏移量配置,kafka代理/协调器将从分区中删除消耗量偏移量。 Next time the saram queries from kafka broker where the offset is, of course client gets nothing. 下次saram从kafka代理查询偏移量在哪里时,客户端当然什么也没得到。 Notice we are using sarama.OffsetOldest as initial value, then sarama client will consume messages from the start of messages kept by kafka broker, which results in messages reconsuming, and this is likely to happen because log retention is 7days 注意,我们使用sarama.OffsetOldest作为初始值,然后sarama客户端将从kafka代理保存的消息开始处消耗消息,这导致消息重用,这很可能发生,因为日志保留时间为7天

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM