迭代式MapReduce
我写了一个简单的k-means聚类代码,用于Hadoop(分成两个程序 - mapper和reducer)。这个代码在我本地的小数据集(二维点)上运行得很好。它是用Python写的,我打算使用Streaming API。
我想请教一下,如何在Hadoop上最好地运行这个程序。
每次运行mapper和reducer后,都会生成新的中心点。这些中心点会作为下一次迭代的输入。
根据我的观察,每次mapreduce的迭代都需要单独作为一个mapreduce任务。而且看起来我还得写另一个脚本(用python或bash)来从HDFS中提取每次reduce阶段生成的新中心点,然后再把它们输入到mapper中。
有没有其他更简单、更不麻烦的方法?如果集群使用的是公平调度器,这样计算完成会不会很慢?
4 个回答
Hadoop的Java接口有一个概念,就是可以把多个工作串联起来一起执行:http://developer.yahoo.com/hadoop/tutorial/module4.html#chaining
不过,因为你在使用Hadoop Streaming,所以没有办法支持工作串联和管理工作流程。
你可以看看Oozie,它可以帮你完成这个任务:http://yahoo.github.com/oozie/
你不需要再写一个新的任务。你可以把同样的任务放在一个循环里(比如说一个 while 循环),然后不断地改变任务的参数。这样,当处理完的 mapper 和 reducer 完成工作后,控制就会开始创建一个新的配置,然后你就会自动得到一个输入文件,这个文件就是上一个阶段的输出。
感觉有点好笑,我在回答我自己的问题。我使用的是PIG 0.9(虽然还没正式发布,但可以在开发版本中找到)。这个版本支持模块化和流程控制,可以把PIG语句嵌入到像Python这样的脚本语言中。
所以,我写了一个主要的Python脚本,里面有一个循环,然后在这个循环里调用我的PIG脚本。我的PIG脚本又调用了用户定义的函数(UDFs)。所以我总共写了三个不同的程序。但结果还不错。
你可以在这里查看示例 - http://www.mail-archive.com/user@pig.apache.org/msg00672.html
顺便说一下,我的用户定义的函数也是用Python写的,利用了这个新功能,可以用脚本语言来编写UDFs。