为什么Kafka实例常常发生Rebalance(重平衡),导致消息拉取失败?
消费组的Rebalance就是对Topic分区的重新分配。
正常情况下消费组内加入新的消费者或老的消费者退出都会导致Rebalance,这种情况是无法避免的。但是某些特殊情况下,消费者会被服务端认为异常从而被踢出消费组,此时可能会导致消费异常,需要重点关注。
消费者被服务端认为异常从而被踢出消费组的场景如下:
- 未能及时发送心跳请求。
消费者以设置的heartbeat.interval.ms为间隔向broker发送心跳请求,如果broker在session.timeout.ms时间内没有收到消费者的心跳请求,broker会认为消费者异常,从而将其从消费组中踢出,然后开始新一轮的Rebalance。
- 消费者消费时间间隔过长。
消费者每次最多消费max.poll.records条消息,多数情况下客户端都会把一次消费到的数据处理完后才会开始下一次消费,如果单次消费的消息太多导致无法在max.poll.interval.ms时间内处理完或消息处理流程发生了异常(如需要写入后端数据库,后端数据库压力太大,慢SQL,时延增加等)导致消费时间增加,在max.poll.interval.ms时间内消费者没有发起下一次消费请求,broker认为消费者不活跃而将其踢出消费组,然后开始新一轮的Rebalance。
解决方法/排查思路
场景一:未能及时发送心跳请求
排查思路:如果是Java语言客户端,建议排查GC日志是否存在长时间FullGC的情况。该场景可能会导致心跳线程阻塞,服务端检查心跳失败,进入Rebalance状态。
解决方法:如果存在长时间FullGC的情况,需要您排查客户端相关问题(FullGC可能是客户端存在内存泄露)。
场景二:消费者消费时间间隔过长
排查思路:
- 检查单条消息的处理时间是多久,处理max.poll.records条消息会不会超过max.poll.interval.ms时间。
- 消息处理流程是否有网络行为,如写数据库、调用后端API等,在发生Rebalance的场景下消费者下游系统是否正常。
解决方法:建议在消费者客户端将max.poll.records值减小,如果消息处理时间较长可以适当增加max.poll.interval.ms。