問題起因
前些天生產上的一套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