我正在使用Java中的newAPIHadoopRDD
读取MongoDB集合。
首先,我使用以下类创建一个JavaSparkContext
对象:
public class SparkLauncher {
public JavaSparkContext javaSparkContext ;
public SparkLauncher()
{
javaSparkContext = null;
}
public JavaSparkContext getSparkContext() {
if (javaSparkContext == null ) {
System.out.println("SPARK INIT...");
try {
System.setProperty("spark.executor.memory", "2g");
Runtime runtime = Runtime.getRuntime();
runtime.gc();
int numOfCores = runtime.availableProcessors();
numOfCores=3;
SparkConf conf = new SparkConf();
conf.setMaster("local[" + numOfCores + "]");
conf.setAppName("WL");
conf.set("spark.serializer",
"org.apache.spark.serializer.KryoSerializer");
javaSparkContext = new JavaSparkContext(conf);
} catch (Exception ex) {
ex.printStackTrace();
}
}
return javaSparkContext;
}
public void closeSparkContext(){
javaSparkContext.stop();
javaSparkContext.close();
javaSparkContext= null;
}
}
然后,在其他课程中我读了mongodb集合:
SparkLauncher sc = new SparkLauncher();
JavaSparkContext javaSparkContext = sc.getSparkContext();
try {
interactions = javaSparkContext.newAPIHadoopRDD(mongodbConfig,
MongoInputFormat.class, Object.class, BSONObject.class);
}
catch (Exception e) {
System.out.print(e.getMessage());
}
这段代码创建了很多线程来读取集合的分裂。关闭JavaSparkContext对象后:
javaSparkContext.close();
sc.closeSparkContext();
System.gc();
所有线程仍处于活动状态且内存未释放。它会导致内存泄漏和线程泄漏。这是因为newAPIHadoopRDD方法吗?有没有办法摆脱这些线程?
答案 0 :(得分:1)
似乎有connection leakage problem mongo-hadoop。运行从mongodb流式传输数据的示例代码后,我可能会遇到同样的问题。
似乎是最新版本1.4.2修复,它在示例代码中对我来说很好。 将您的maven依赖关系更改为:
<dependency>
<groupId>org.mongodb.mongo-hadoop</groupId>
<artifactId>mongo-hadoop-core</artifactId>
<version>1.4.2</version>
</dependency>
答案 1 :(得分:0)
我没有将Spark与MongoDB一起使用,很可能无法完全回答你的问题,但我的评论很少,可能会导致解决方案。
System.setProperty("spark.executor.memory", "2g")
对您的Spark环境无效,因为您使用local
模式,其中一个且只有一个执行程序的内存量是在启动时分配给应用程序的内存(并且不能更改)。您最好不要删除该线路或切换到其他Spark部署环境,例如独立,YARN或Mesos。
conf.set("spark.executor.instances", "10")
,因为最多只能有runtime.availableProcessors()
或numOfCores
个帖子来启动任务。在所有只有一个JVM最多有local
个线程用于执行任务的情况下,您正在使用Runtime.getRuntime().availableProcessors()
模式。 Spark最终将释放Spark使用的线程。它们所属的线程池已作为SparkContext.stop
的一部分关闭(在您的示例中看不到它被调用,但由于我使用的是Scala API,因此可能存在差异)。
答案 2 :(得分:0)