其实文章名可以叫 记一次线上 Kafka 问题排查,但觉得稀松平常,弄些术词显得硬核点,hhh,言归正传,线上一个 Go 服务是一组 Kafka 的消费者,在运行了很多天之后,Kafka 数据突然积压了,查看 Kafka 服务正常,查看 Go 服务也运行正常,进到 Go 服务容器内部查看日志,发现消费者的 Go 服务频繁 rebalance 并且大概率返回失败。因为我们所使用的 Kafka 分配的分区为3,所以 Go 服务 一个 Deployment 三个 Pod。
错误信息如下:
kafka server: The provided member is not known in the current generation
Request was for a topic or partition that does not exist on this broker
有时候日志里还会伴随着
i/o timeout
甚至还触发了 阿里云的 K8s 运营报警,在代码中加了 errors 和 notifications 日志,发现每次错误都伴随着 rebalance。
一开始以为是超时时间过短导致,调大了连接超时和读写超时的时间,但是问题没有得到解决。
又以为是我们 Go 服务处理业务逻辑问题,性能不足,导致处理时间过长,以至于 Kafka Server 认为 Client 死掉了,然后进行rebalance 导致的,于是将每条获取到的 message 放到 channel 中,弄了一个线程池去消费 channel 来解决问题,但是问题仍然没有解决。 阅读了 sarama 的 heartbeat 机制,发现每个 consumer 都有单独的 goroutine 每 3 秒发送一次心跳。因此这个处理时间应该只会导致消费速度下降,不会导致 rebalance。
于是只好另外启动了一个消费者,指定了另外一个 group id,来做测试,在消费过程中,发现并未发生 rebalance。这时我就裂开了,懵逼了。得亏我最近查文档技能点满了,终于翻到一篇文章看到了这个问题的解决方案,全文英语,我就不贴出来了,简单概括讲下:
而我之前出问题的 Go 服务所使用的的消费组 groupId 在不同 Topic 下都有多个消费者。为了验证这个问题,我修改了我的消费组的 groupId,加了后缀与其它消费者区分开,果然之前频繁 reblance 再也没有发生过 reblance了。
此处评论已关闭