【问题标题】:How do I find all combinations of keys in a hadoop data set?如何找到 hadoop 数据集中的所有键组合?
【发布时间】:2017-06-23 05:03:48
【问题描述】:

我的数据结构如下:

A, 23
B, 324235
C, 123
D, 213

示例字数映射器具有以下映射函数签名:

public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {

核心问题:

Text value 只是输入文件中的一行,或者一个键。如何一次访问所有密钥?似乎这些行(以及它们为以后减少而展开的扩展)不知道其他输入行

示例用法:

我正在寻找输出所有 ID 组合,这要求键“相互了解”

AB
AC
AD
BC
BD
CD

编辑:天真的方法/直觉

我认为实现它的一种方法是使用映射器将每一行映射到同一个键,然后在减速器中

映射器的结果:

CONST_KEY, A
CONST_KEY, B
CONST_KEY, C
CONST_KEY, D

减速机:

public void reduce(Text key, Iterable<Text> values, Context context){

//PSEUDO CODE
  for(int i = 0; i < values.length; i++){
      for(int j = i+1; j < values.length; j++){
          String combo = concat(values[i], values[j]);
       }
  } 
}

但这似乎是疯狂的低效

【问题讨论】:

  • 这个问题符合 MapReduce 生成的排列类别。见stackoverflow.com/questions/6535878/permutations-with-mapreduce
  • 更糟糕的是,您编写 reduce 的方式无法正常工作,因为您无法像那样访问 values。 Hadoop 不允许您访问值列表,您可以遍历值一次。如果你想做更多,你需要自己将它们存储在内存中。

标签: java hadoop


【解决方案1】:

我只会得到键集,然后做一个嵌套的 for 循环来创建结果:

List<String> keys = new ArrayList<String>(yourmap.keySet());
List<String> results= new ArrayList<String>();

for(int i = 0; i < keys.length - 1; i++)
    for (int j = i+1; j < keys.length; j++)  {
        results.add(keys.get(i) + keys.get(j))
    }
}

【讨论】:

  • 如果您可以读取内存中的整个文件,这会起作用,但它似乎不会扩展到 hadoop 使用的 map reduce 模型,除非我遗漏了一些非常明显的东西(我的错我原来的问题标题太模糊了,因为已经编辑)
【解决方案2】:

您可能至少有三个选择来实现这一目标:

  1. WholeFileInputFormat

您可以编写自定义输入格式,将整个文件作为记录。您可以在 Tom Whites 的 Hadoop 书籍 here 的代码中看到一个示例。

  1. 在 Mapper 中维护状态

随着每条记录进入映射器,每次迭代都会生成新的组合。或者更简单的方法是将记录添加到列表中,一旦所有记录都被读取,使用 Mapper 的 cleanup() 方法生成所有组合。

  1. 使用减速器

您可以使用一个公共键从 Mapper 发出每个条目,所有值都将作为可以迭代的值列表进入 reduce。然后,您需要有逻辑来生成所有组合。

问题确实是,如果您有多个文件,因此多个映射器并行运行,12 不起作用。只要唯一的密钥集适合内存,3 就可以工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 2013-12-30
    • 1970-01-01
    相关资源
    最近更新 更多