Hadoop 编写MApreduce代码以计算记录数

Hadoop 编写MApreduce代码以计算记录数,hadoop,mapreduce,Hadoop,Mapreduce,我想写一个mapreduce代码来计算给定CSV文件中的记录数。我不知道在map中该做什么,在reduce中该做什么。我应该如何解决这个问题?有人能提出一些建议吗? 您的映射应该为每个读取的记录发出1 您的组合器应该发出它得到的所有“1”的总和(每个贴图的小计) 您应该发出记录总数的 您的映射器必须发出一个固定键(只需使用值为“count”的文本)和一个固定值1(与您在wordcount示例中看到的相同) 然后简单地使用一个减速机 作业的输出将是一个带有键“count”的记录,该值是您正在查找的

我想写一个mapreduce代码来计算给定CSV文件中的记录数。我不知道在map中该做什么,在reduce中该做什么。我应该如何解决这个问题?有人能提出一些建议吗?

  • 您的映射应该为每个读取的记录发出1
  • 您的组合器应该发出它得到的所有“1”的总和(每个贴图的小计)
  • 您应该发出记录总数的

您的映射器必须发出一个固定键(只需使用值为“count”的文本)和一个固定值1(与您在wordcount示例中看到的相同)

然后简单地使用一个减速机

作业的输出将是一个带有键“count”的记录,该值是您正在查找的记录数


您可以选择(显著地!)通过使用与组合器相同的LongSumReducer来提高性能。

使用job.getcounters()检索在作业完成后每个记录增加的值。如果您正在使用java编写mapreduce作业,则使用枚举计数机制。

import java.io.IOException;
import java.io.IOException;

import java.util.*;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.*;

import org.apache.hadoop.mapred.*;

public class LineCount 

{
    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("Total Lines");

    public void map(LongWritable key, Text value,
            OutputCollector<Text, IntWritable> output,Reporter reporter)
            throws IOException 
    {
        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(LineCount.class);

    conf.setJobName("LineCount");
    conf.setNumReduceTasks(5);
    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);
}
}
导入java.util.*; 导入org.apache.hadoop.fs.Path; 导入org.apache.hadoop.io.*; 导入org.apache.hadoop.mapred.*; 公共类行计数 { 公共静态类映射扩展了MapReduceBase实现 制图员 { 私有最终静态IntWritable one=新的IntWritable(1); 专用文本字=新文本(“总行”); 公共无效映射(可长写键、文本值、, OutputCollector输出,报告器(报告器) 抛出IOException { 输出。收集(字,一); } } 公共静态类Reduce扩展了MapReduceBase实现 减速器{ public void reduce(文本键、迭代器值、, OutputCollector输出,报告器(报告器) 抛出IOException{ 整数和=0; while(values.hasNext()){ sum+=values.next().get(); } collect(key,newintwriteable(sum)); } } 公共静态void main(字符串[]args)引发异常{ JobConf conf=newjobconf(LineCount.class); conf.setJobName(“行计数”); conf.setNumReduceTasks(5); 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); } }
我只想使用身份映射器和身份缩减器

这是Mapper.class和Reducer.class。然后只需读取
地图输入记录


你真的不需要做任何编码就能得到这个

希望我有一个比公认答案更好的解决方案

我们为什么不在map()中增加一个计数器,并在cleanup()中的每个map任务之后发出增加的计数器,而不是为每个记录发出1呢

可以减少中间读写操作。并且reducer只需要聚合少数值的列表

public class LineCntMapper extends
  Mapper<LongWritable, Text, Text, IntWritable> {

 Text keyEmit = new Text("Total Lines");
 IntWritable valEmit = new IntWritable();
 int partialSum = 0;

 public void map(LongWritable key, Text value, Context context) {
  partialSum++;
 }

 public void cleanup(Context context) {
  valEmit.set(partialSum);

   context.write(keyEmit, valEmit);

 }
}
公共类LineCntMapper扩展
制图员{
Text key emit=新文本(“总行”);
IntWritable valEmit=新的IntWritable();
int partialSum=0;
公共void映射(可长写键、文本值、上下文){
partialSum++;
}
公共空间清理(上下文){
瓦莱米特集(部分);
write(keyEmit,valEmit);
}
}

您可以找到完整的工作代码

谢谢您的回答。您能告诉我什么是LongSumReducer以及它与普通reducer有何不同吗?LongSumReducer是reducer的一个简单实现,它完全满足您的需要。所以你不必自己写。我在回答中向文档添加了URL。您能告诉我如何使用LongSumReducer吗?你能给我提供一个代码片段来帮助我吗?当你试图自己写的时候,这段代码是微不足道的。签出Hadoop教程()或一本好的Hadoop书籍,并尝试自己编写。这不是一个“别人做我的作业”的网站。优雅而高效的解决方案。