我是Hadoop的新手。我希望使用分层聚类对大约1.5亿个项目进行聚类,每个项目具有~30个属性。维度/属性总数约为5000。
我设计了一个多级解决方案,它通过对整个数据进行分区并在每个分区上执行群集并在那之后合并每个群集,直到检索到所需数量的群集。
- Clustering is performed in each map task. So, each map task would be cpu-intensive.
- I am stuck at deciding about which of the following options to use:
- Map-Reduce in native Java.
- Map-Reduce using Hadoop Streaming on C.(This is because of each task being cpu-intensive).
Which option should I go with?. Is there any other way I could achieve my destination?
答案 0 :(得分:4)
在许多情况下,Java(编写得很好)将产生与C类似的性能,除非仔细优化C代码。在很多情况下,编写良好的Java代码 优于C代码,因为C代码在编译时进行了优化,而Java热点编译器在运行时进行了优化(其中有关每个代码路径使用频率的统计信息。
如果您收集了类似的统计信息,并且它们不会根据您的数据进行更改,您有时可以向C编译器提供提示,例如:使用某些C编译器中提供的__builtin_expect()
。但这真的很难做到。
但请记住,Java的某些部分价格相当高:
Collection<Integer>
,ArrayList<Double>
等进行计算。这些在热循环中确实非常昂贵。BufferedReader
更快的I / O. Hadoop使用Text
代替String
是有原因的 - 缓冲区回收降低了I / O成本。对于hadoop,请记住 Hadoop流媒体不是免费的。如果您还没有意识到: hadoop-streaming本身是用Java实现的。所有数据都将通过Java传递。 Hadoop流是一个Java应用程序,它启动您的脚本应用程序,向其写入数据(即序列化数据!),并读回输出(反序列化数据!)。除了实际的程序成本之外,你几乎得到了所有的Java成本:hadoop streaming是一个用Java编写的映射器,它将数据传递给外部程序,读回答案,并将其返回给Hadoop。将用C语言编写的单词计数与Java中的优化单词计数进行基准比较,以查看差异。
对于您的实际任务,做HAC:首先确保您的工作相似性。没有什么比建立大规模聚类算法更糟糕的了,只是为了发现它不起作用,因为你无法以有意义的方式测量相似性。 首先解决小样本上的问题,然后按比例放大。
答案 1 :(得分:2)
如果真的很重要,你必须分析每一个。没有办法预先告知。
我的直觉是,直接的Java实现将执行类似于本机C的操作,除非您开始手动优化后者。
请记住,MapReduce通常具有较高的IO时间,特别是在从文本文件中读取时。因此,做几百次KMeans或计算SVD可能并不那么昂贵。所以你也想测量那个方面。