问题起因
前些天生产上的一套Kafka集群吞吐量异常高,根据Grafana监控发现主要数据TPS来自 __consumer_offsets
队列。
其他业务TOPIC总TSP才几百+,而kafka内部Topic __consumer_offsets
达到33.85k,这现象明显不正常啊。
排查思路
首先怀疑是不是监控出问题了,Prometheus Exporter有bug? 还是Grafana Metrics写错了?又看了看其他集群的监控,发现并不是监控工具的问题。
然后登陆到kafka集群后台服务器,查看一下这个topic的LOG-END-OFFSET情况,使用kafka命令行工具kafka-consumer-groups.sh
,间隔5分钟采集多次,然后计算一下每秒的增量,发现和监控显示的吞吐量基本吻合。
__consumer_offsets 22 - 2729106 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 30 - 0 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 8 - 2902605 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 21 - 0 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 4 - 26901884 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 27 - 1173895 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 7 - 829529641 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 9 - 1788460542 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 46 - 0 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
__consumer_offsets 25 - 0 - consumer-10656153-9fd2bbbb-6e4f-41d1-9b60-2bbcf387bd65 /xxx.xxx.xxx consumer-10656153
......
顺便说一下Kafka的内部队列
__consumer_offsets
的作用,kafka默认将这个topic分成了50个partition,用于存储consumer group每次commit的offset信息,目的是为了在consumer重启后或者在增减消费者时,可以根据此offset信息继续消费。
Consumer Group 对应Partition计算规则:Math.abs(groupID.hashCode()) % numPartitions
Topic中存储的消息格式:[Group, Topic, Partition]::[OffsetMetadata[Offset, Metadata], CommitTime, ExpirationTime]
分析到了这里,造成__consumer_offsets
吞吐量过高的真相只有一个了,就是业务端的应用服务中的consumer group提交的频次过高。
既然已经定位了问题了 ,那么去追查具体服务就OK了吧,现实情况显然不是这样的,使用这套kafka集群的平台是一个非常庞大的业务系统,150+的微服务,具体哪些服务和kafka相关,哪些是消费者,估计都得梳理几天。。。
分析工具
既然已经知道问题产生的原因,同时也了解kafka内部队列__consumer_offsets
的存储策略,那么写个程序去读取该topic的消息,然后分析哪些consumer group的提交频次过高,根据group name便可以直接定位具体是哪个微服务了。
coding......
开始表演show time.......
根据定位到的异常微服务排查发现,有使用offset自动提交,但是auto.commit.interval设置了100ms,也有使用手动提交offset,但无数据消费时仍然提交offset。。。太坑了
此后,代码质量的checkpoint项中增加关于kafka使用的检查。
最后分享一下工具GitHub地址:kafka-offset-consumer