我在火花流应用程序中遇到了驱动程序进程的问题。问题是驱动程序进程内存不足。主节点和工作节点都没有问题(它们都可以连续好几天运行)。但即使使用非常有限的馈送(每5分钟发送两条消息,处理1条消息的时间不到100毫秒),我会在一段时间后(例如周末)在驱动程序进程中出现oom错误。
以下是更多详情:
我有一个简单的spark-streaming应用程序,它使用来自mqtt数据源的事件并将它们存储在数据库中。我使用了一个带有1个主节点和2个工作节点的小火花簇。我有一个驱动程序进程(开始使用带有部署模式客户端的spark-submit)为集群提供服务。我正在使用Java8(Oracle VM)在Ubuntu上运行spark-1.4.1-bin-hadoop2.6。
我的驱动程序基本上如下:
JavaReceiverInputDStream<String> messages = createInputDStream(ssc);
messages.mapPartitions(...).mapToPair(...).updateStateByKey(...).
foreachRDD(rdd -> {
rdd.foreach(ne -> {
});
return null;
});
我已经做过初步调查。如果我采用驱动程序进程的堆转储来收集实例的直方图(jmap -histo),我通常会看到这样的东西:
1: 36388 81204168 [B
2: 407486 32826432 [C
3: 40849 25067224 [I
4: 367245 8813880 scala.collection.immutable.$colon$colon
5: 311000 7464000 java.lang.String
6: 114294 7314816 org.apache.spark.storage.RDDInfo
我注意到,随着时间的推移,RDDInfo对象的数量正在增加。堆转储显示大量RDDINfo对象保留在JobProgressListener的stageIdToData映射中。看一下那个类的代码,似乎应该把丢失的旧数据丢掉。因此,我已经设置了
spark.ui.retainedJobs 50
spark.ui.retainedStages 50
在conf / spark-defaults.conf中。但这没有任何帮助。从我的转储中,我看到这个stageIdToData映射包含1897个条目。鉴于上述配置设置,这看起来很奇怪。
我在这里做错了什么,或者这是一个火花问题?