目录
一,事件回顾
二,问题原因
三,发生问题时的日志
四,避免此问题
1,auto.offset.reset参数设置为largest。
2,尽量不要一次关闭所有broker。
五,相关知识点
1,zookeeper记录offset的节点
2,关于auto.offset.reset参数。
3,几个kafka的命令
一,事件回顾
1,由3台broker组成的kafka集群,分别标记为broker0,broker1,broker2,某topic有3个副本,分别保存在这三个broker上。
2,某日broker0挂了,broker1和broker2好像也有点问题,于是关闭consumer,把broker1和broker2也关闭,然后按照broker0,broker1,broker2的顺序依次启动,并启动consumer。
3,发现这个topic积压了大量消息,积压量几乎和broker队列中的所有消息一样多,也就是说,consumer将要把队列中之前消费过的所有消息又重新消费一遍,造成了重复消费。
二,问题原因
问题的关键在于consumer的auto.offset.reset这个参数,这个参数在zookeeper中记录的当前消费offset超出broker中记录的offset队列范围时生效(该参数生效的场景不止这一种),发生问题的系统中这个参数设置的是smallest,代表consumer在参数生效时会从队列最小offset重新开始消费。
然后就是复现当时的场景了,也就是为什么zookeeper中记录的offset会超过broker消息队列中的offset范围,大概是下面这样的:
1,当系统还正常时:
consumer消费到了offset=200的消息,3个副本间同步正常,zookeeper中的offset记录为200。
2,broker0挂掉,重新进行了leader选举,broker1成为新的leader,于是变成下面这样:
3,此时producer没停,又向队列中放了2条消息,于是变成下面这样: