我有一个关于在 Hadoop 中为多个映射器配置 Map/Side 内部连接的问题。
假设我有两个非常大的数据集 A 和 B,我使用相同的分区和排序算法将它们分成更小的部分。对于 A,假设我有 a(1) 到 a(10),而对于 B,我有 b(1) 到 b(10)。确保 a(1) 和 b(1) 包含相同的 key ,a(2) 和 b(2) 具有相同的 key ,依此类推。我想设置 10 个映射器,特别是映射器(1)到映射器(10)。据我了解,Map/Side join 是 mapper 之前的预处理任务,因此,我想加入 a(1) 和 b(1) for mapper(1),加入 a(2) 和 b( 2) 用于映射器(2),依此类推。
看了一些引用资料,我还是不太清楚这十个mapper是怎么配置的。我知道使用 CompositeInputFormat 我将能够加入两个文件,但似乎只配置了一个映射器并成对加入了 20 个文件(在 10 个连续任务中)。如何在真正的 Map/Reduce(并行 10 个任务)中配置所有这十个映射器并同时加入十个对?据我了解,十个映射器需要十个 CompositeInputFormat 设置,因为要加入的文件全都不同。我坚信这是实用且可行的,但我无法弄清楚我应该使用哪些确切的命令。
任何提示和建议都受到高度欢迎和赞赏。
施
非常感谢大卫和托马斯的回复!
感谢您对 Map-side Join 的先决条件的强调。是的,我知道排序、API 等。阅读您的评论后,我认为我的实际问题是在 CompositeInputFormat 中连接两个文件的多个拆分的正确表达式是什么。例如,我将 dataA 和 dataB 分别排序和减少到 2 个文件中:
/A/dataA-r-00000
/A/dataA-r-00001
/B/dataB-r-00000
/B/dataB-r-00001
我现在使用的表达式命令是:
内部(tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,"/A/dataA-r-00000"),tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,"/B/dataB-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 具有不重叠的键)。
或者我可以只使用两个目录作为输入,例如:
String joinexpression = "inner(tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,'/A/'),tbl(org.apache.hadoop.mapred.KeyValueTextInputFormat,'/B/'))";
内连接将根据文件结尾自动匹配对,比如“00000”到“00000”,“00001”到“00001”?我被困在这一点上,因为我需要构造表达式并将其传递给
conf.set("mapred.join.expr", joinexpression);
所以一句话,如果我想使用更多的映射器同时连接多对文件,我应该如何构建正确的表达式?
最佳答案
有 map- 和 reduce 侧连接。
您建议使用 map 侧连接,它在映射器内部而不是在它之前执行。
双方必须具有相同的键和值类型。因此,您不能加入 LongWritable
和 Text
,尽管它们可能具有相同的值。
还有一些微妙的注意事项:
整个过程基本上是这样工作的:你有数据集 A 和数据集 B,它们共享相同的 key ,比如
LongWritable
。如果要加入的文件数量不相等,则会导致作业设置过程中出现异常。
设置连接有点痛苦,主要是因为如果你的版本低于 0.21.x,你必须使用旧的 API 来映射器和化器。
This document describes very well how it works. 一直滚动到底部,遗憾的是在最新的 Hadoop 文档中不知何故缺少此文档。
另一个很好的引用是“Hadoop the Definitive Guide”,它更详细地解释了所有这些并附有示例。
关于hadoop - 在 Hadoop Map/Reduce 中为多个映射器配置 Map Side join,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6323544/