繁体   English   中英

如何在Java中使用newAPIHadoopRDD读取MongoDB集合后停止线程?

[英]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方法吗? 有没有办法摆脱这些线程?

这是仍然活着的部分线程的快照: 在此输入图像描述

以下是使用jconsole的程序的内存使用情况: 在此输入图像描述

最后,eclipse内存分析器中的漏洞可疑: 在此输入图像描述

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,因此可能存在差异)。

我做了另一个实验。 这次我只是编写了一个简单的代码来在一个循环中使用相同的方法读取一个Mongo集合,并进行了15次迭代。 在循环结束时,我也调用System.gc()以防万一。

以下是此代码的jconsole输出,它显示了运行期间累积的线程。 在此输入图像描述

我还使用MongoDB api实现了代码,而在另一个集合中没有newAPIHadoopRDD(见下图): 在此输入图像描述 一段时间后,内存使用率变得固定。 但是当我使用newAPIHadoopRDD读取相同的集合时,请查看内存使用情况和线程: 在此输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM