【问题标题】:Join of two datasets in Mapreduce/Hadoop在 Mapreduce/Hadoop 中加入两个数据集
【发布时间】:2012-08-01 23:00:03
【问题描述】:

有人知道如何在 Hadoop 中实现两个数据集之间的 Natural-Join 操作吗?

更具体地说,这就是我真正需要做的:

我有两组数据:

  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。我想要做的是将所有 point_id:point_info 对与每个 tile_number 的所有 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)

【问题讨论】:

    标签: hadoop join mapreduce distributed


    【解决方案1】:

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

    所以地图输出会是这样的:

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

    然后,在 reducer 中,您的输入将具有以下结构:

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

    你必须将点和线分开,做一个叉积并输出每对叉积,像这样:

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

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

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

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

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

    tile(current key), element_of_the_resulting_cross_product_list
    

    【讨论】:

    • 太棒了。但是我应该如何在reduce部分做叉积呢?
    • 很好,但这只有在您可以将整个点/线放入内存中以便将它们存储在提到的两个列表中时才有效。恐怕在我的大型数据集中情况并非如此:(
    • 这篇文章已经很老了,但是因为我有一个与此非常相似的问题,所以在这里发帖。有人可以在此处提供示例代码示例,说明如何以 map/reduce 格式执行此操作。我正在努力理解和学习这一点。提前致谢
    • @reza 你有没有为大型数据集找到上述解决方案??
    【解决方案2】:

    所以基本上你在这里有两个选择。Reduce side join 或 Map Side Join。

    这里你的组键是“tile”。在单个减速器中,您将获得点对和线对的所有输出。但是您必须在阵列中缓存点对或线对。如果任何一对(点或线)都非常大,以至于您的临时数组内存都不能容纳单个组键(每个唯一的图块),那么此方法对您不起作用。请记住您不必将单个组密钥(“tile”)的两个密钥对都保存在内存中,一个就足够了

    如果单个组密钥的两个密钥对都很大,那么您将不得不尝试 map-side join。但是它有一些特殊的要求。但是,您可以通过一些 map/reduce 作业对数据进行一些预处理来满足这些要求,这些作业为两个数据运行相同数量的 reducer。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 2015-04-07
      相关资源
      最近更新 更多