Mapreduce将值链接到每个键的列表中

时间:2016-12-07 09:54:59

标签: hadoop mapreduce

我有一个小项目,我正在做mapreduce,因为我是新的,我遇到了很多困难,所以会提供帮助。 在这个prjoect我有一个文件,其中包含一个站点和标签(每个站点有10个标签)我想通过共享标签找到每个站点的simmilar站点。 所以例如3个站点这是我的数据集

site1   tag1
site1   tag2
site1   tag3
site1   tag4
site1   tag5
site2   tag1
site2   tag2
site2   tag3
site2   tag11
site2   tag12
site3   tag1
site3   tag11
site3   tag13
site3   tag14
site3   tag15

(本例中我为每个站点只做了5次)。 我想要做的是做一个mapreduce,键将是标记并重视网站。 我希望每个标记都能获得具有此标记的网站列表(或数组或其他) 所以在这个例子中:

tag1: site1, site2, site3
tag2: site1,site2
tag3: site1, site2
tag4: site1 

等等 然后在列表上运行,对于每个公共对,在它旁边给出一个1的vaule,所以看起来像这样

tag1: site1_site2 1, site1_site3 1, site2_site3 1
tag2: site1_site2 1

等等 然后链接另一个mapreduce作业以对每对的值求和 我为它写了这段代码

public static class TokenizerMapper extends Mapper<Object, Text, Text, Text>{

    private Text site = new Text();
    private Text tag = new Text();
    public void map(Object key, Text value, Context context) 
                       throws IOException, InterruptedException {
        StringTokenizer itr = new StringTokenizer(value.toString(), "\t");
        while (itr.hasMoreTokens()) {
            site.set(itr.nextToken());
            tag.set(itr.nextToken());
            context.write(tag, site);
        }
    }
}

public static class tagCount extends Reducer<Text,IntWritable,Text,Text> {

    public void reduce(Text key, Iterable<Text> values, Context context) 
                             throws IOException, InterruptedException {
        String res = "";
        while (values.iterator().hasNext()) {
            res = res + "," + values.iterator().next();
        }
        Text result = new Text(res);
        context.write(key, result);
    }
}

public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf, "tag count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(tagCount.class);
    job.setReducerClass(tagCount.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(Text.class);
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
}

我的第一个问题是如何将减速器中的值链接在一起? 从现在开始我就得到一份

列表
tag1 site1
tag1 site2 

等等 我试图设置一个字符串,当我迭代值以将下一个标记添加到字符串但它无法正常工作

非常感谢您的帮助

1 个答案:

答案 0 :(得分:1)

这里重新编写了减速机,以帮助您入门:

sites

要点:

  • 您需要构建值的内部集合。在这种情况下,我使用了一个字符串列表,这是最安全的方式,直到您熟悉Hadoop如何重用对象。
  • 此代码假定SequenceFileOutputFormat不会变大,因此改进是在其大小周围添加一些检查,因为我们将其放入内存并且以下context.write将正在扩大数据。
  • 然后,您遍历网站并生成排列,将每个网站写出来。
  • 使用SequenceFileInputFormat写出数据,然后您的下一个作业可以使用Text,输入映射器的类型将为IntWritable#define buffer (*(uint8_t (*)[240][320])0xE30014)