在Hadoop Map / Reduce中为多个映射器配置Map Side连接

时间:2011-06-12 17:54:26

标签: hadoop mapreduce inner-join

我有一个关于在Hadoop中为多个映射器配置Map / Side内部连接的问题。 假设我有两个非常大的数据集A和B,我使用相同的分区和排序算法将它们分成更小的部分。对于A,假设我有(1)到a(10),而对于B我有b(1)到b(10)。确保a(1)和b(1)包含相同的键,a(2)和b(2)具有相同的键,依此类推。我想设置10个映射器,特别是映射器(1)到映射器(10)。据我所知,Map / Side join是mapper之前的预处理任务,因此,我想加入a(1)和b(1)for mapper(1),加入a(2)和b( 2)用于mapper(2),依此类推。

在阅读了一些参考资料后,我仍然不清楚如何配置这十个映射器。我知道使用CompositeInputFormat我可以连接两个文件,但它似乎只配置一个映射器并在配对后加入20个文件对(在10个连续任务中)。如何配置所有这十个映射器并在真正的Map / Reduce中同时连接十对(并行10个任务)?根据我的理解,十个映射器需要十个CompositeInputFormat设置,因为要加入的文件都是不同的。我坚信这是实用和可行的,但我无法弄清楚我应该使用哪些确切的命令。

任何提示和建议都非常受欢迎和赞赏。


非常感谢大卫和托马斯的回复!

感谢您对Map-side Join的预先要求的重视。是的,我知道sort,API等。在阅读你的评论后,我认为我的实际问题是在CompositeInputFormat中连接两个文件的多个拆分的正确表达式是什么。例如,我将dataA和dataB分别按2个文件排序和缩小:

/ A /数据A-R-00000

/ A /数据A-R-00001

/ B /数据B-R-00000

/ B /数据B-R-00001

我现在使用的表达式命令是:

内(TBL(org.apache.hadoop.mapred.KeyValueTextInputFormat, “/ A /数据A-R-00000”),TBL(org.apache.hadoop.mapred.KeyValueTextInputFormat,“/ B /数据B-R-00000 “))

它可以工作,但正如你所提到的,它只启动两个映射器(因为内连接阻止分裂),如果文件很大,效率可能非常低。如果我想使用更多的映射器(比如另外2个映射器加入dataA-r-00001和dataB-r-00001),我应该如何构造表达式,如下所示:

String joinexpression =“inner(tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,'/ A / dataA-r-00000'),tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,'/ B / dataB -r-00000'),tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,'/ A / dataA-r-00001'),tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,'/ B / dataB-r -00001'))“;

但我认为这可能是错误的,因为上面的命令实际上执行了四个文件的内部连接(在我的情况下不会产生任何结果,因为文件* r-00000和* r-00001具有非重叠键)。 / p>

或者我可以使用两个目录作为输入,例如:

String joinexpression =“inner(tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,'/ A /'),tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,'/ B /'))”; < / p>

内连接会根据文件结尾自动匹配对,说“00000”到“00000”,“00001”到“00001”?我陷入困境,因为我需要构建表达式并将其传递给

conf.set(“mapred.join.expr”,joinexpression);

总而言之,如果我想使用更多映射器同时连接多对文件,我应该如何构建正确的表达式呢?

2 个答案:

答案 0 :(得分:4)

有map-reduce和side连接。 您建议使用地图侧连接,该连接在映射器内执行而不是在映射器之前执行。 双方必须具有相同的键和值类型。因此,您无法加入LongWritableText,但它们可能具有相同的值。

还有一些细微的注意事项:

  • 输入文件必须进行排序,因此它可能是减速器输出
  • 您可以通过设置作业中应该对数据集进行排序的缩减器数量来控制连接映射阶段中的映射器数量

整个过程基本上是这样的:你有数据集A和数据集B,两者共享相同的密钥,比方说LongWritable

  1. 运行两个作业,按照键对两个数据集进行排序,两个作业都必须将减速器的数量设置为相等的数字,例如2。
  2. 这将为每个数据集生成2个已排序文件
  3. 现在你设置加入数据集的作业,这个作业将产生2个映射器。如果你在之前的工作中将减少数量设置得更高,可能会更多。
  4. 在减少步骤中做任何你喜欢的事。
  5. 如果要连接的文件数不相等,则会在作业设置期间导致异常。

    设置连接有点痛苦,主要是因为如果你的版本小于0.21.x,你必须使用旧的API for mapper和reducer。

    This document describes very well how it works.一直滚动到底部,遗憾的是,最新的Hadoop文档中遗漏了这些文档。

    另一个很好的参考是“Hadoop the Definitive Guide”,它更详细地解释了所有这些并带有示例。

答案 1 :(得分:1)

我认为你错过了这一点。您无法控制映射器的数量。这是你可以控制的减速器数量。只需从映射器中发出正确的密钥即可。然后运行10个减速器。