[英]How to stop threads after reading a MongoDB Collection using newAPIHadoopRDD in Java?
我正在使用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方法吗? 有没有办法摆脱这些线程?
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>
我不使用带有Spark的MongoDB,很可能无法完全回答你的问题,但我的评论很少,可能会导致解决方案。
System.setProperty("spark.executor.memory", "2g")
对您的Spark环境无效,因为您使用local
模式,其中一个且仅一个执行程序的内存量是您分配的内存量在启动时应用程序(并且永远不能更改)。 您最好删除线路或切换到其他Spark部署环境,例如Standalone,YARN或Mesos。
conf.set("spark.executor.instances", "10")
因为只有numOfCores
runtime.availableProcessors()
或numOfCores
线程才能启动任务。 毕竟你只有一个JVM,而Runtime.getRuntime().availableProcessors()
线程用于执行任务,你就是在使用local
模式。 Spark最终将释放Spark使用的线程。 它们所属的线程池已作为SparkContext.stop
一部分关闭(在您的示例中看不到它被调用,但由于我使用的是Scala API,因此可能存在差异)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.