YARN 上的 Spark Streaming - Java 运行时环境内存不足,无法继续

Spark Streaming on YARN - There is insufficient memory for the Java Runtime Environment to continue

这是 YARN 集群模式下的 Spark Streaming 应用程序 运行,它在三个 Kafka 代理中生成消息。

一旦打开文件数达到 150K,它就会失败:

There is insufficient memory for the Java Runtime Environment to continue
Native memory allocation (mmap) failed  to map 12288 bytes for committing reserved memory.

Job aborted due to stage failure ... : 
org.apache.kafka.common.KafkaException: Failed to construct kafka producer
.....
Caused by: java.lang.OutOfMemoryError: unable to create new native thread

当为运行该执行程序的 java 进程执行 lsof -p <PID> 时,我可以看到来自 Kafka 代理中主机服务器的大量(最多 90K)TCP 连接:

host:portXXX->kafkabroker1:XmlIpcRegSvc (ESTABLISHED)

host:portYYY->kafkabroker2:XmlIpcRegSvc (ESTABLISHED)

host:portZZZ->kafkabroker3:XmlIpcRegSvc (ESTABLISHED)

我尝试将执行程序内核的数量从 8 个减少到 6 个,但打开文件的数量没有任何差异(仍然达到 150K),然后一直失败。

从 Spark Streaming 连接到 Kafka 的库是:

org.apache.spark.streaming.kafka010.KafkaUtils
org.apache.spark.streaming.dstream.InputDStream
org.apache.kafka.clients.producer.kafkaproducer

代码:

foreachRDD{
   get kafkaProducer
   do some work on each RDD...
   foreach( record => {
      kafkaProducer.send(record._1,record._2)
   }
  kafkaProducer.close()
}

这是一个小学生的错误。这很好地解释 article 帮助解决了这个问题。 kafka producer 没有关闭连接,所以我们使用广播和惰性求值技术解决了这个问题。