Spark的KMeans无法处理bigdata吗?

时间:2016-09-01 00:05:52

标签: python apache-spark k-means apache-spark-mllib bigdata

KMeans的training有几个参数,初始化模式默认为kmeans ||。问题是它快速(不到10分钟)前进到前13个阶段,然后完全挂起,而不会产生错误!

再现问题的

最小示例(如果我使用1000点或随机初始化,它将会成功):

from pyspark.context import SparkContext

from pyspark.mllib.clustering import KMeans
from pyspark.mllib.random import RandomRDDs


if __name__ == "__main__":
    sc = SparkContext(appName='kmeansMinimalExample')

    # same with 10000 points
    data = RandomRDDs.uniformVectorRDD(sc, 10000000, 64)
    C = KMeans.train(data, 8192,  maxIterations=10)    

    sc.stop()

这项工作什么都不做(它没有成功,失败或进步......),如下所示。 “执行程序”选项卡中没有活动/失败的任务。 Stdout和Stderr Logs没有什么特别有趣的事情:

enter image description here

如果我使用k=81而不是8192,它将会成功:

enter image description here

请注意两次调用takeSample()should not be an issue,因为在随机初始化的情况下调用了两次。

那么,发生了什么? Spark的Kmeans 无法扩展?有人知道吗?你可以重现吗?

如果是内存问题,I would get warnings and errors, as I had been before

注意:placeybordeaux的评论是基于客户端模式中作业的执行,其中驱动程序的配置无效,导致退出代码143等(见编辑历史记录),而不是群集模式,根本没有报告错误,应用程序只挂起

从032开始:Why is Spark Mllib KMeans algorithm extremely slow?是相关的,但我认为他见证了一些进展,而我的确悬而未决,我确实发表评论......

enter image description here

2 个答案:

答案 0 :(得分:5)

我认为'悬挂'是因为你的遗嘱执行人不断死亡。正如我在旁边的会话中提到的,这个代码对我来说很好,本地和群集,Pyspark和Scala。但是,它需要更长的时间。几乎所有时间花在k-means ||上初始化。

我打开了https://issues.apache.org/jira/browse/SPARK-17389来跟踪两个主要改进,其中一个可以立即使用。编辑:真的,另见https://issues.apache.org/jira/browse/SPARK-11560

首先,有一些代码优化可以将init加速大约13%。

然而,大多数问题是它默认为k-means ||的5个步骤init,当看起来2几乎总是那么好。您可以将初始化步骤设置为2以查看加速,尤其是在现在挂起的阶段。

在笔记本电脑上的(较小的)测试中,初始时间从5:54变为1:41,两次更改都是由于设置了初始化步骤。

答案 1 :(得分:1)

如果您的RDD太大,collectAsMap将尝试将RDD中的每个元素复制到单个驱动程序中,然后耗尽内存并崩溃。即使您已对数据进行了分区,collectAsMap也会将所有内容发送给驱动程序,您的作业也会崩溃。 您可以通过调用take或takeSample或者过滤或采样RDD来确保返回的元素数量有上限。 同样,除非您确定数据集大小足以适合内存,否则请谨慎对待这些其他操作:

countByKey, countByValue, 收集

如果确实需要RDD的这些值中的每一个并且数据太大而无法容纳到内存中,您可以将RDD写出到文件或将RDD导出到足够大的数据库以容纳所有数据。当您使用API​​时,我认为您无法做到这一点(可能会重写所有代码?增加内存?)。我认为在runmegorithm方法中的这个collectAsMap在Kmeans(https://databricks.gitbooks.io/databricks-spark-knowledge-base/content/best_practices/dont_call_collect_on_a_very_large_rdd.html)中是一件非常糟糕的事情......