【问题标题】:Got OutOfMemory when run Spark MLlib kmeans运行 Spark MLlib kmeans 时出现内存不足
【发布时间】:2016-11-26 22:46:35
【问题描述】:

我在大数据集上运行 Spark Kmeans 时总是遇到 OutOfMemory 错误。训练集大约 250GB,我有 10 个节点 spark 集群,每台机器有 16 个 cpu 和 150G 内存。我在每个节点上为作业提供 100GB 内存和总共 50 个 CPU。我将集群中心设置为 100,迭代次数为 5。但是当代码在以下行上运行时,我得到了 OutOfMemory:

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

请问有什么参数可以调整来解决这个问题。

如果我设置较小的聚类中心数或迭代数就可以了。

我的代码如下:

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")

我的输入格式如下:

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.

我得到的异常如下:

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)

【问题讨论】:

    标签: apache-spark machine-learning apache-spark-mllib apache-spark-ml


    【解决方案1】:

    默认情况下,Spark 的 Kmeans 实现使用 K_MEANS_PARALLEL 初始化模式。此模式的一部分在驱动程序机器上运行,并且可能非常慢/导致驱动程序出现 OOM,具体取决于您的数据。

    尝试切换到RANDOM初始化模式。

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

    要尝试的另一件事是在提交申请时增加驱动程序内存。例如,使用以下命令将驱动内存设置为 4G

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

    【讨论】:

    • 非常感谢,它解决了我的问题。请我再问一个问题:为什么我每次都得到不同的结果,即使我总是设置我的 numCluster=10 和 numIteration=5。
    • K-means 是一种优化算法,因此不同的初始质心(由于随机初始化)会导致不同的聚类。
    • 谢谢,实际上我仍然遇到 OutOfMemory 异常,请更新我的问题并提供更多信息。
    • 尝试增加你的驱动内存,看看我更新的答案。
    • 非常感谢,它有效!其实我设置的Master总内存是30g,我以为客户端会把它当作驱动内存。只知道我必须设置 spark.driver.memory。尴尬,虽然我用 Spark 多年了,我才知道这个配置。
    猜你喜欢
    • 2015-07-08
    • 2015-12-13
    • 2015-06-14
    • 2017-07-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 2014-12-14
    相关资源
    最近更新 更多