Java mapreduce计数示例

Java mapreduce计数示例,java,hadoop,mapreduce,Java,Hadoop,Mapreduce,我的问题是关于java中的mapreduce编程 假设我有WordCount.java示例,一个标准的mapreduce程序。我希望map函数收集一些信息,然后返回reduce函数maps,其格式如下: 这样我就可以知道哪个从属节点收集了哪些数据。。知道怎么做吗 public class WordCount { public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, T

我的问题是关于java中的mapreduce编程

假设我有WordCount.java示例,一个标准的
mapreduce程序
。我希望map函数收集一些信息,然后返回reduce函数maps,其格式如下:

这样我就可以知道哪个从属节点收集了哪些数据。。知道怎么做吗

public class WordCount {

    public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> {
      private final static IntWritable one = new IntWritable(1);
      private Text word = new Text();

      public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
        String line = value.toString();
        StringTokenizer tokenizer = new StringTokenizer(line);
        while (tokenizer.hasMoreTokens()) {
          word.set(tokenizer.nextToken());
          output.collect(word, one);
        }
      }
    }

    public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> {
      public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
        int sum = 0;
        while (values.hasNext()) {
          sum += values.next().get();
        }
        output.collect(key, new IntWritable(sum));
      }
    }

    public static void main(String[] args) throws Exception {
      JobConf conf = new JobConf(WordCount.class);
      conf.setJobName("wordcount");

      conf.setOutputKeyClass(Text.class);
      conf.setOutputValueClass(IntWritable.class);

      conf.setMapperClass(Map.class);
      conf.setCombinerClass(Reduce.class);
      conf.setReducerClass(Reduce.class);

      conf.setInputFormat(TextInputFormat.class);
      conf.setOutputFormat(TextOutputFormat.class);

      FileInputFormat.setInputPaths(conf, new Path(args[0]));
      FileOutputFormat.setOutputPath(conf, new Path(args[1]));

      JobClient.runJob(conf);
    }
}
公共类字数{
公共静态类映射扩展MapReduceBase实现映射器{
私有最终静态IntWritable one=新的IntWritable(1);
私有文本字=新文本();
公共void映射(LongWritable键、文本值、OutputCollector输出、Reporter报告器)引发IOException{
字符串行=value.toString();
StringTokenizer标记器=新的StringTokenizer(行);
while(tokenizer.hasMoreTokens()){
set(tokenizer.nextToken());
输出。收集(字,一);
}
}
}
公共静态类Reduce扩展MapReduceBase实现Reducer{
公共void reduce(文本键、迭代器值、OutputCollector输出、Reporter报告器)引发IOException{
整数和=0;
while(values.hasNext()){
sum+=values.next().get();
}
collect(key,newintwriteable(sum));
}
}
公共静态void main(字符串[]args)引发异常{
JobConf conf=newjobconf(WordCount.class);
conf.setJobName(“字数”);
conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(IntWritable.class);
conf.setMapperClass(Map.class);
conf.setCombinerClass(Reduce.class);
conf.setReducerClass(Reduce.class);
conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);
setInputPath(conf,新路径(args[0]);
setOutputPath(conf,新路径(args[1]);
runJob(conf);
}
}

谢谢

您要求的是让应用程序(您的map reduce thingy)了解它所运行的基础架构

一般来说,答案是应用程序不需要这些信息。对映射器的每次调用和对Reducer的每次调用都可以在不同的节点上执行,也可以全部在同一节点上执行。MapReduce的美妙之处在于结果是相同的,因此对于您的应用程序来说:这并不重要

因此,API没有支持您的此请求的功能

享受学习Hadoop的乐趣:)


另外,我能想到的唯一方法(至少可以说是令人讨厌的)是在映射器中包含某种系统调用,并询问底层操作系统关于它的名称/属性等。
这种构造将使您的应用程序非常不可移植;i、 它不会在Windows或Amazon的Hadoop上运行。

Wordcount是一个错误的例子。您只需要将所有信息合并在一起。这与字数相反

基本上,您只是将slaveNode_id作为一个
可写
(如果可能的话)发送,而信息则作为
文本

  public static class Map extends MapReduceBase implements Mapper<LongWritable, Text,IntWritable, Text> {
    private Text word = new Text();

  public void map(LongWritable key, Text value, OutputCollector<IntWritable, Text> output, Reporter reporter) throws IOException {
    String line = value.toString();
    StringTokenizer tokenizer = new StringTokenizer(line);
    while (tokenizer.hasMoreTokens()) {
      word.set(tokenizer.nextToken());
      // you have to split your data here: ID and value
      IntWritable id = new IntWritable(YOUR_ID_HERE);

      output.collect(id, word);
    }
  }
}
公共静态类映射扩展MapReduceBase实现映射器{
私有文本字=新文本();
公共void映射(LongWritable键、文本值、OutputCollector输出、Reporter报告器)引发IOException{
字符串行=value.toString();
StringTokenizer标记器=新的StringTokenizer(行);
while(tokenizer.hasMoreTokens()){
set(tokenizer.nextToken());
//您必须在此处拆分数据:ID和值
IntWritable id=新的IntWritable(此处为您的id);
输出.收集(id,word);
}
}
}
减速器的工作原理是一样的:

 public static class Reduce extends MapReduceBase implements Reducer<IntWritable, Text,IntWritable, Text> {
  public void reduce(IntWritable key, Iterator<Text> values, OutputCollector<IntWritable,Text> output, Reporter reporter) throws IOException {

      // now you have all the values for a slaveID as key. Do whatever you like with that...
      for(Text value : values)
         output.collect(key, value)
  }
}
公共静态类Reduce扩展MapReduceBase实现Reducer{
公共void reduce(IntWritable键、迭代器值、OutputCollector输出、Reporter报告器)引发IOException{
//现在你有了slaveID的所有值作为键。用它做任何你喜欢的事情。。。
用于(文本值:值)
收集输出(键、值)
}
}

不完全正确,他在数据中有关于从机的信息:。Wordcount将此转换为,他希望以另一种方式获取slaveNode收集的所有信息。无法从MR应用程序中知道slaveNode的id。我可以在MR程序中使用slave_node_id而不打印任何内容吗?关键是数据将按哪个节点使用什么进行分类。但是用户没有必要看到节点_id如果你根本没有它怎么看使用什么东西(比如从节点_id)?!?!?有意思。。但我的问题仍然是。。如何从程序中获取从节点id?该映射将为reducer映射提供信息,其中信息为type class,属性为我从internet获得的一些信息。那么它有什么问题呢。运行我的代码后,您将使用slave_node_id作为键以及与之关联的所有值。然后您可能有一个sequencefile,可以在其中迭代并查看结果。你真的应该先去看一本教程,我读过这方面的书,然后我在这里问。。在你的身份证里,你是什么意思?我在哪里可以找到这个ID?我希望你的数据是文本文件,看起来像这样,对吗?因此,“”是在映射器中得到的文本对象内部的内容。您必须从该文本对象中解析从属节点id。然后你必须发出这个ID作为你的密钥,这样hadoop就可以对它进行排序。并将具有相同键的所有值合并在一起。这就是你想要的吗?