0

Ich bekam immer OutOfMemory Fehler, wenn ich Spark Kmeans auf große Datenmenge ausgeführt habe. Das Training Set über 250 GB, ich habe 10 Knoten Funken Cluster jede Maschine mit 16 CPUs und 150G Speicher. Ich gebe dem Job 100 GB Speicher auf jedem Knoten und 50 CPUs total. Ich habe das Cluster Zentrum 100 und Iteration 5. Ich aber bekam OutOfMemory, wenn der Code in der folgenden Zeile wurde ausgeführt:OutOfMemory bei der Ausführung Spark MLlib kmeans

val model = KMeans.train(parsedData, numClusters, numIterations) 

Gibt es einen Parameter kann ich tune das Problem zu beheben bitte.

Wenn ich kleinere Cluster-Center-Nummer oder Iterationsnummer setzen, wäre es in Ordnung.

My-Code wie folgt:

val originalData = sc.textFile("hdfs://host/input.txt").cache() 
val tupleData = originalData.map { x => (x.split(":")(0),x.split(":")(1)) } 
val parsedData = tupleData.map { x => x._1 }.map(s => Vectors.dense(s.split(',').map(_.toDouble))) 

val model = KMeans.train(parsedData, numClusters, numIterations, 1, initializationMode = KMeans.RANDOM) 
val resultRdd = tupleData.map { p => (model.predict(Vectors.dense(p._1.split(',').map(_.toDouble))),p._2)} 
resultRdd.sortByKey(true, 1).saveAsTextFile("hdfs://host/output.txt") 

Mein Eingabeformat wie folgt:

0.0,0.0,91.8,21.67,0.0 ... (the element number is 100K) 
1.1,1.08,19.8,0.0,0.0 ... 
0.0,0.08,19.8,0.0,0.0 ... 
... 
The rows number is 600K. 

Die Ausnahme, die ich bekam, wie folgend:

scheduler.DAGScheduler: Submitting ShuffleMapStage 42 (MapPartitionsRDD[49] at map at KmeansTest.scala:47), which has no missing parents 
Exception in thread "dag-scheduler-event-loop" java.lang.OutOfMemoryError: Java heap space 
    at java.util.Arrays.copyOf(Arrays.java:2271) 
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:113) 
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93) 
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:140) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1876) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1785) 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1188) 
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) 

Antwort

4

Durch die Standard-Spark-Kmeans Implementierung Verwendung K_MEANS_PARALLEL Initialisierungsmodus. Ein Teil dieses Modus wird auf dem Treibercomputer ausgeführt und kann abhängig von Ihren Daten sehr langsam sein und OOM im Treiber verursachen.

Versuchen Sie, in den Initialisierungsmodus RANDOM zu wechseln.

Eine andere Sache zu versuchen ist, Ihren Fahrergedächtnis zu erhöhen, wenn Sie Ihre Anwendung einreichen. Verwenden Sie zum Beispiel den folgenden Befehl, um den Treiberspeicher auf 4G zu setzen:

spark-submit --conf "spark.driver.memory=4g" ... 
+0

Vielen Dank, es hat mein Problem behoben. Könnte ich noch eine Frage stellen: warum habe ich jedes Mal ein anderes Ergebnis bekommen, obwohl ich immer numCluster = 10 und numIteration = 5 gesetzt habe. – Jack

+1

K-Means ist ein Optimierungsalgorithmus, daher können verschiedene Anfangsschwerpunkte (aufgrund zufälliger Initialisierung) zu unterschiedlichen Clustern führen. – Dikei

+0

Vielen Dank, ich habe die OutOfMemory-Ausnahme immer noch erfüllt, ich habe meine Frage mit weiteren Informationen aktualisiert. – Jack

Verwandte Themen