Kafka问题(3):Failed to allocate memory within the configured max blocking time 60000 ms

记录kafka出现的问题,原因,与对应场景下的解决方案.
造成问题方式有很多种,这里只是记录遇到的或已知的,若有遗漏情况欢迎补充
由于问题很多出现在生产环境,故敏感信息已屏蔽,不影响问题介绍

环境

  • linux
  • jdk1.8
  • kafka-client 0.10.x.x
  • kafka-server 0.10.x.x

问题

kafka-Client报错如下

com.mym.test.exception.MsgSendFailException: org.apache.kafka.common.errors.TimeoutException: Failed to allocate memory within the configured max blocking time 60000 ms.
        at com.mym.test.handler.produce.Producer10$1.onCompletion(Producer10.java:30)
        at org.apache.kafka.clients.producer.KafkaProducer.doSend(KafkaProducer.java:479)
        at org.apache.kafka.clients.producer.KafkaProducer.send(KafkaProducer.java:430)
        at com.mym.test.handler.produce.Producer10.add(Producer10.java:24)
        at com.mym.test.handler.Delivery.add(Delivery.java:154)
        at com.mym.test.DeliveryUtils.sendDataToDelivery(DeliveryUtils.java:66)
        at com.mym.test.common.Commons.sendPairDataToDelivery(Commons.java:71)
        at com.mym.test.handler.SDKStatHandler.run(SDKStatHandler.java:194)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.kafka.common.errors.TimeoutException: Failed to allocate memory within the configured max blocking time 60000 ms.

重点

Caused by: org.apache.kafka.common.errors.TimeoutException: Failed to allocate memory within the configured max blocking time 60000 ms.

分析原因

从报错信息可知,在配置的最大的阻塞时间内分配内存失败了。再解释下就是,由于异步发送,数据需要先放到缓冲区里,但是分配内存分配了blocking time这么长的时间还是分配失败,就报错了。

  • 出此报错信息一般是因为kafka集群内部有问题 或着客户端方面原因
  • 涉及几个配置项:再用这几个配置项来解释就是:当kafka-client向kafka某个分区发数据时,等了linger.ms或积累了batch.size量我就会发出去,否则就会先把数据放到buffer.memory这个大小的缓冲区里,往这个缓冲区里放失败时最多阻塞重试max.block.ms长时间,否则就抛出异常。
                    <!-- 发送总缓冲区大小(字节),默认值33554432 -->
                    <property name="buffer.memory" value="33554432"/>
                    <!-- 发送总缓冲区慢了之后最大阻塞时长,超过时长后将抛出异常,默认值60000 ms -->
                    <property name="max.block.ms" value="60000"/>
                    <!-- 单分区一次请求最大批次,默认值16384? -->
                    <property name="batch.size" value="32768"/>
                    <!-- 单分区一次请求最大批次等待时间,默认值0 ms? -->
                    <property name="linger.ms" value="5"/>
                    <!-- 单次请求包体最大大小,默认值1048576.不能超过服务端设置的接受包体最大值? -->
                    <property name="max.request.size" value="3145728"/>
  • 可能因为某些原因或参数配置不合理,导致(用生产者消费者来说这个缓冲区的话)生产数据比消费数据快,导致总会有一个时间点爆满buffer.memory并且阻塞达到max.block.ms就报错。生产数据比消费数据快的情景有很多种,也就是实际上会有很多原因造成这个报错。(例如根本不消费数据,即缓冲区数据不会减少)
  • 由于如果网络问题是好的且kafka集群ok的话,那此问题极有可能是参数设置不合理。因为如果可以往外发,但是发送失败的话,消息是会做过期处理,不会一直占着缓冲区

参考解决思路

  • 一般kafka集群出了问题短时间自动恢复后,kafka-client也能感知到也能自动恢复。
  • 长时间挂掉的话,kafka-client可能也死了,就需要手动干预重启kafka-clien或通过其他干预或检测手段来恢复,一般思路原理就是重建连或手动让旧kafka-client连接再次尝试链接
  • 确定kafka-client与kafka-server无网络问题
  • 检查参数是否设置合理
  • zk上查看kafka是否有broker掉线
  • 逐一检查kafka的log,看是否有报错或有效信息,一般要多看点日志,kafka集群除了点问题,如果集群够大,可能恢复也要一定时间,这短时间可能仍然无法使用
  • Kafka问题(2):Batch containing 5 record(s) expired due to timeout while requesting metadata from broker也会造成此问题。因为kafka挂了,数据就发不出去,就会一直存在缓冲区,源源不断的数据加入缓冲区就会满掉报错

造成问题方式有很多种,这里只是记录遇到的或已知的,若有遗漏情况欢迎补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值