Mapreduce/Hoop中两个数据集的连接



有人知道如何在Hadoop中实现两个数据集之间的自然联接操作吗?

更具体地说,我需要做的是:

我有两组数据:

  1. 存储为(tile_number,point_id:point_info)的点信息,这是一个1:n键值对。这意味着对于每个tile_number,可能有几个point_id:point_info

  2. 存储为(tile_number,Line_id:Line_info)的行信息,这也是1:m键值对,对于每个tile_number来说,可能有不止一个Line_id:Line_info

正如您所看到的,两个数据集之间的tile_numbers是相同的。现在,我真正需要的是基于每个tile_number来连接这两个数据集。换句话说,对于每个tile_number,我们有n个point_id:point_info和m个line_id:line_info。我想做的是将每个tile_number 的所有point_id:point_info对与line_id:line_info对连接起来


为了澄清,这里有一个例子:

对于点对:

(tile0, point0)
(tile0, point1)
(tile1, point1)
(tile1, point2)

对于线路对:

(tile0, line0)
(tile0, line1)
(tile1, line2)
(tile1, line3)

我想要的是:

对于磁贴0:

 (tile0, point0:line0)
 (tile0, point0:line1)
 (tile0, point1:line0)
 (tile0, point1:line1)

对于磁贴1:

 (tile1, point1:line2)
 (tile1, point1:line3)
 (tile1, point2:line2)
 (tile1, point2:line3)

使用一个映射器,将标题输出为键,将点/线输出为值。您必须区分点输出值和线输出值。例如,您可以使用一个特殊字符(即使二进制方法会更好)。

因此,地图输出将类似于:

 tile0, _point0
 tile1, _point0
 tile2, _point1 
 ...
 tileX, *lineL
 tileY, *lineK
 ...

然后,在减速器上,您的输入将具有以下结构:

 tileX, [*lineK, ... , _pointP, ...., *lineM, ..., _pointR]

你必须把点和线分开,做一个叉积,然后输出每对叉积,就像这样:

tileX (lineK, pointP)
tileX (lineK, pointR)
...

如果您已经可以很容易地区分点值和线值(取决于您的应用程序规范),则不需要特殊字符(*,_)

关于您必须在减速器中进行的叉积:您首先遍历整个值List,将它们分成2个列表:

 List<String> points;
 List<String> lines;

然后使用2个嵌套for循环进行叉积。然后对结果列表进行迭代,并为每个元素输出:

tile(current key), element_of_the_resulting_cross_product_list

所以这里基本上有两个选项。减少边连接或映射边连接。

这里你的组密钥是"tile"。在一个归约器中,你将得到点对和线对的所有输出。但是您必须在数组中缓存点对或线对。如果其中一对(点或线)非常大,都无法放入单个组键(每个唯一瓦片)的临时数组内存,则此方法将不适用。记住对于内存中的单个组密钥("tile"),您不必同时持有两个密钥对,一个就足够了

如果单个组密钥的两个密钥对都很大,那么您将不得不尝试映射侧连接。但它有一些特殊的要求。然而,您可以通过一些映射/减少作业对数据进行预处理来满足这些要求,这些作业为两个数据运行相同数量的减少器。

相关内容

  • 没有找到相关文章