在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?