Ich lese eine MongoDB-Sammlung mit newAPIHadoopRDD in Java. Zuerst erstelle ich ein JavaSparkContext Objekt mit der folgenden Klasse:

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;     
    }   
}

Dann las ich in einer anderen Klasse die Mongodb-Sammlung:

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());
    }

Dieser Code erstellt viele Threads, die die Teilungen der Sammlung lesen. Nachdem ich das JavaSparkContext-Objekt geschlossen habe:

javaSparkContext.close();
sc.closeSparkContext();
System.gc();

Alle Threads sind noch aktiv und der Speicher wird nicht freigegeben. Es verursacht eine Art Speicher- und Thread-Leck. Liegt das an der neuen APIHadoopRDD-Methode? Gibt es eine Möglichkeit, diese Threads loszuwerden?

Hier ist eine Momentaufnahme eines Teils der Threads, die noch am Leben sind: Bildbeschreibung hier eingeben

Hier ist die Speichernutzung des Programms mit jconsole: Bildbeschreibung hier eingeben

Und schließlich der Leckverdächtige im Eclipse Memory Analyzer: Bildbeschreibung hier eingeben

3
Morteza Mashayekhi 23 Dez. 2015 im 22:54

2 Antworten

Beste Antwort

Es scheint ein Verbindungsleck zu geben Problem mit Mongo-Hadoop. Ich konnte das gleiche Problem feststellen, nachdem ich einen Beispielcode ausgeführt hatte, der Daten von Mongodb gestreamt hatte.

Es scheint mit der neuesten Version 1.4.2 behoben zu sein, und es funktioniert gut für mich im Beispielcode. Ändern Sie Ihre Maven-Abhängigkeit in:

<dependency>
    <groupId>org.mongodb.mongo-hadoop</groupId>
    <artifactId>mongo-hadoop-core</artifactId>
    <version>1.4.2</version>
</dependency>
1
zoran jeremic 16 Jän. 2016 im 19:01

Ich habe noch ein Experiment gemacht. Dieses Mal habe ich nur einen einfachen Code geschrieben, um eine Mongo-Sammlung mit derselben Methode in einer Schleife mit 15 Iterationen zu lesen. Am Ende der Schleife rufe ich für alle Fälle auch System.gc() auf.

Hier ist die jconsole-Ausgabe für diesen Code, die die Ansammlung von Threads während des Laufs anzeigt. Bildbeschreibung hier eingeben

Ich habe den Code auch mit MongoDB-API und ohne newAPIHadoopRDD in einer anderen Sammlung implementiert (siehe folgende Tabelle): Bildbeschreibung hier eingeben Nach einer Weile wird die Speichernutzung behoben. Aber siehe Speichernutzung und Threads, als ich newAPIHadoopRDD verwendete, um dieselbe Sammlung zu lesen: Bildbeschreibung hier eingeben

0
M. Mashaye 15 Jän. 2016 im 20:52