背景:

kafka测试集群,5台节点

问题描述:

生产者发送消息失败概率大,尤其是连接建立的时候。查看内存信息,发现cpu占用过高,一直发生gc

查找原因:

查找kafka服务日志,发现5号节点有如下报错:

kafka生产者发送对象 kafka生产者发送失败_kafka生产者发送对象

top命令详解

top -d 1

kafka生产者发送对象 kafka生产者发送失败_kafka_02

jstat -gcutil 23518

kafka生产者发送对象 kafka生产者发送失败_kafka_03

jmap -heap 23518

kafka生产者发送对象 kafka生产者发送失败_kafka_04

kafka生产者发送对象 kafka生产者发送失败_JVM_05

jstat参数说明:S0C:第一个幸存区的大小
  S1C:第二个幸存区的大小
  S0U:第一个幸存区的使用大小
  S1U:第二个幸存区的使用大小
  EC:伊甸园区的大小
  EU:伊甸园区的使用大小
  OC:老年代大小
  OU:老年代使用大小
  MC:方法区大小
  MU:方法区使用大小
  CCSC:压缩类空间大小
  CCSU:压缩类空间使用大小
  YGC:年轻代垃圾回收次数
  YGCT:年轻代垃圾回收消耗时间
  FGC:老年代垃圾回收次数
  FGCT:老年代垃圾回收消耗时间
  GCT:垃圾回收消耗总时间

解决办法:

将kafka-server-start.sh中的KAFKA_HEAP_OPTS调大

默认为:KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"

正常生产环境建议:KAFKA_HEAP_OPTS="-Xmx6G -Xms6G"

资源充足并且kafka任务比较多:KAFKA_HEAP_OPTS="-Xmx15G -Xms15G"


09-25补充修改:

由于 Kafka 并未大量使用堆上内存( on-the-heap memory )而是使用堆外内存( off-the-heap memory ),故不需要为 Kafka 设定太大的堆空间。生产环境中 6GB 通常是足够了的,
要知道以 Linkedln 公司 1500+台的 Kafka 集群规模来说,其 JVM 设置中也就是 6GB 的堆大
小。另外,由于是 Java ,因此推荐使用 Gl 垃圾收集器。–apache kafka实战 胡夕

如果上面的修改不管用的话,用下面这种方法试试:

修改/usr/local/kafka/binkafka-run-class.sh
-XX:MaxDirectMemorySize加大,该参数默认是64M,可以根据需求调大,
如果没找到,就在KAFKA_JVM_PERFORMANCE_OPTS添加,
并且检查JVM参数里面有无:-XX:+DisableExplicitGC,如果有就去掉。

理由:

堆内存由JVM自己管理,堆外内存必须要由我们自己释放;
一般使用显示gc:System.gc来触发,但是这只是建议,不一定被jvm会执行.
-XX:+DisableExplicitGC会使显示gc禁用。

增大MaxDirectMemorySize的值可以参考