在Hadoop中链接多个MapReduce作业
在许多应用MapReduce的真实情况下,最终的算法最终会成为几个MapReduce步骤。
即Map1,Reduce1,Map2,Reduce2等等。
因此,您需要将最后一次减少的输出作为下一个地图的输入。
中间数据是您(一般情况下)在管道成功完成后不想保留的内容。 另外,因为这个中间数据通常是一些数据结构(如'map'或'set'),所以您不希望在编写和读取这些键值对时付出太多努力。
在Hadoop中推荐的方式是什么?
是否有一个(简单)示例显示如何以正确的方式处理这些中间数据,包括之后的清理?
我认为这个关于雅虎开发人员网络的教程将帮助你:链接作业
您使用JobClient.runJob()
。 来自第一份工作的数据的输出路径成为您的第二份工作的输入路径。 这些需要作为参数传递给您的作业,并使用适当的代码来解析它们并为作业设置参数。
我认为上面的方法可能是现在较老的mapred API做的,但它仍然可以工作。 在新的mapreduce API中会有类似的方法,但我不确定它是什么。
至于在作业完成后删除中间数据,您可以在代码中执行此操作。 我之前做过的方式是使用类似于:
FileSystem.delete(Path f, boolean recursive);
路径是数据HDFS上的位置。 您需要确保只有在没有其他工作需要时才删除此数据。
有很多方法可以做到这一点。
(1)级联工作
为第一个作业创建JobConf对象“job1”,并将所有参数设置为“input”作为输入目录,“temp”作为输出目录。 执行此工作:
JobClient.run(job1).
紧接着它,为第二个作业创建JobConf对象“job2”,并将所有参数设置为“temp”作为输入目录,“输出”作为输出目录。 执行此工作:
JobClient.run(job2).
(2)除了不使用JobClient.run之外,创建两个JobConf对象并将其中的所有参数设置为(1) 。
然后用jobconfs作为参数创建两个Job对象:
Job job1=new Job(jobconf1);
Job job2=new Job(jobconf2);
使用jobControl对象,可以指定作业依赖关系,然后运行作业:
JobControl jbcntrl=new JobControl("jbcntrl");
jbcntrl.addJob(job1);
jbcntrl.addJob(job2);
job2.addDependingJob(job1);
jbcntrl.run();
(3)如果你需要一个像Map + |的结构 减少| Map *,您可以使用Hadoop版本0.19及之后的ChainMapper和ChainReducer类。
干杯
实际上有很多方法可以做到这一点。 我将专注于两个。
一个是通过Riffle(http://github.com/cwensel/riffle)一个注释库来识别相关事物,并以依赖(拓扑)顺序“执行”它们。
或者您可以在Cascading(http://www.cascading.org/)中使用Cascade(和MapReduceFlow)。 未来版本将支持Riffle注释,但现在使用原始MR JobConf作业效果很好。
一个变种就是不用手工管理MR作业,而是使用Cascading API开发你的应用程序。 然后,JobConf和作业链通过Cascading planner和Flow类在内部处理。
通过这种方式,您可以专注于自己的问题,而不是管理Hadoop作业的机制等。甚至可以将顶层的不同语言(如clojure或jruby)分层以进一步简化开发和应用程序。 http://www.cascading.org/modules.html
链接地址: http://www.djcxy.com/p/67705.html上一篇: Chaining multiple MapReduce jobs in Hadoop
下一篇: What's the difference between faking, mocking, and stubbing?