问题现象
SRE收到了磁盘空间占用告警,但该服务器主要运行控制服务,很少产生持久化数据,查看了Grafana,也确认是近期磁盘占用率涨的飞快。
进入服务器检查,发现是Kafka Manager产生了大量的容器日志,配置了容器stdout/stderr
的max-size
后,日志得到收缩,告警解除。接着分析大量刷新日志的原因,发现是不断报错无法解析固定一个Kafka集群的消息。
其他录入的集群都没有出现这种日志,单单只有一个集群出现,随即检查了对应Kafka集群的指标,发现生产和消费都是正常的,Zookeeper内的元数据也没有出现紊乱,并且核对过版本,跟录入到Kafka Manager的版本号是一致的。
这里可能跟Kafka自身的问题无关了,至于为何单独这个集群出现,我们慢慢定位。
分析过程
owned_partitions
应该是Kafka的内部属性,并且需要从topic解析,那么推测应该是从__consumer_offsets
里消费的,因为开启了消费监听后,Kafka Manager会通过监听这个内部topic来获取消费者组的消费进度,使用的消费组名称为KMOffsetCache-<id>
,于是查看这个Consumer Group的消费情况。
有client连接消费,数据也确实是从该Kafka集群获取的,针对该client,进行抓包看看。
# ${kafka-manager-host} 为 Kafka Manager 的主机 IP
tcpdump -i bond0 host ${kafka-manager-host} and port 9092 -t -n -vv -w /tmp/kafka.1.cap
对Kafka协议进行TCP追踪发现,出现大量的关于某个Consumer Group的记录。
统计发现,这些Kafka Fetch
请求都是消费__consumer_offsets
的36号分区,因为__consumer_offsets
的分区是根据Group ID的哈希取模得到,意味着这些都来自于同一个Consumer Group ID。
查看Kafka Fetch Response
的响应报文,倒没有错误记录,但是Message Set
的Record Batch
里只有1个条目,看上去Consumer Group没有持续消费的动作。
因为报文里可以分析出对应的Consumer Group名称,尝试查看消费的情况。
这个组在不断的rebalance或者断开连接,非常怪异。但是到这里,已经能猜到大概是什么原因导致Kafka Manager产生频繁的错误日志了。既然一直尝试加入消费或者退出消费,那就直接从Group Coordinator进行抓包分析,首先获取到此Group的Group Coordinator
所在broker。
然后再到服务器上面进行抓包,抓包命令参考上面的tcpdump
即可。将报文在Wireshark上过滤出一份会话进行分析,总的协议交互如下。
首先完成了Kafka JoinGroup
的交互,这个时候,注册了Consumer Group,并且将Group ID进行哈希后分配到__consumer_offsets
对应的Partition来记录,这里就是刚才定位到的36号分区的由来。
紧接着,Kafka Metadata
里开始注册Topic来消费。
但是集群内并没有这些分区,broker也回包说明了ErrorCode 3(Unknown Topic or Partition)
,并且后续Consumer Group进行OffsetFetch
也返回了空的Topic和Partition。
而因为加入阶段,会记录到__consumer_offsets
,这也意味着会被Kafka Manager消费到记录,因为没有对应的Topic或Partition,__consumer_offsets
的Value内的字节序里没有topic_size
和partition_id
的存储,因此在反序列化时,出现了java.nio.BufferUnderflowException
的错误。而接入的Client因为代码重试逻辑不断的发起请求,频繁地重复执行上述过程,导致刷新了大量的错误日志,最终影响磁盘使用。
为了验证,可以分析一下message。
上面是正常的Consumer Group的记录,可以看到记录了Topic,解析Value可以获得Partition ID。但是下面异常的,只记录了JoinGroup
的记录,并没有消费的目标信息,这也与推测的结果一致。
处理结果
在Kafka JoinGroup Request
里可以获取Client对应的IP来源,找到相关的服务进行修复后,日志也停止了疯狂报错。
针对这类问题,可以通过加入ACL的方式来拦截一些外部项目的胡乱接入。而对容器的日志,也统一设置max-size
滚动,避免大量占据日志目录,影响其他服务写入日志。
原文始发于微信公众号(AcidPool):CMAK 解析 Kafka 信息失败的问题分析
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/171018.html