问题背景
某业务hellbat消费名称为swc-sas-nsc-prod-operation-warning的topic,此topic共5个partition,消费组为hellbat_prod,两个consumer实例,其中consumer1消费0、1、2分区,consumer2消费3、4分区。发生问题时,consumer1消费的0、1、2分区的current_offset被重置为0了。
参数配置
consumer配置:auto.offset.reset=earliest,其中consumer1消费的3个分区在24小时内没有新的消息
kakfa配置:kafka server端offsets.retention.minutes=1440(24h)
问题分析
首先kafka server的配置offsets.retention.minutes=1440意义为kafka server会为每个consumer的offset保持24小时的有效期,过期删除offset记录,即删除consumer提交过的offset。此配置为kafka 0.11.0.2的默认配置,未修改过此配置;其次consumer中auto.offset.reset=earliest表示在kafkaserver中如果未发现当前kafka broker中维护过该consumergroup内的consumer offset信息,即从最早的offset开始消费,本例中最早的offset为0,如发现已有维护过该consumer group内的consumer offset信息,即从已提交的offset开始消费;另通过查看kafka client源码确认,consumer每次提交offset都会将自己分配到的partition全部提交;
问题确认
hellbat消费名称为swc-sas-nsc-prod-operation-warning的 topic的0,1,2分区在前24小时内没有任何新消息,kafka server直接删除了自身维护的offset;加上consumer auto.offset.reset=earliest的配置和此三个topic本身消息就很少还未达到kafka segment的存储大小,即kafka本身保留了所有日志消息均为删除,故consumer1从offset重新消费了0,1,2三个分区的消息,下面有具体配置的解释和消费组current_offset的展示:
NAME | DESCRIPTION | TYPE | DEFAULT | VALID VALUES | IMPORTANCE |
offsets.retention.minutes | Log retention window in minutes for offsets topic | int | 1440 | [1,...] | high |
问题解决思路
可以考虑使用rocketmq等其他消息队列处理低吞吐的业务
增大offsets.retention.minutes的配置,由1天改为7天。实际上kafka2.x版本已默认将此参数修改为7天,可参考https://cwiki.apache.org/confluence/display/KAFKA/KIP-186%3A+Increase+offsets+retention+default+to+7+days,另2.1.0版本修正了“无脑”过期位移删除,只对非active的group执行过期位移删除,详细信息参见:https://cwiki.apache.org/confluence/display/KAFKA/KIP-211%3A+Revise+Expiration+Semantics+of+Consumer+Group+Offset
确认auto.offset.reset=earliest的使用场景,根据业务场景调整此配置