Hadoop 编写MApreduce代码以计算记录数
我想写一个mapreduce代码来计算给定CSV文件中的记录数。我不知道在map中该做什么,在reduce中该做什么。我应该如何解决这个问题?有人能提出一些建议吗?Hadoop 编写MApreduce代码以计算记录数,hadoop,mapreduce,Hadoop,Mapreduce,我想写一个mapreduce代码来计算给定CSV文件中的记录数。我不知道在map中该做什么,在reduce中该做什么。我应该如何解决这个问题?有人能提出一些建议吗? 您的映射应该为每个读取的记录发出1 您的组合器应该发出它得到的所有“1”的总和(每个贴图的小计) 您应该发出记录总数的 您的映射器必须发出一个固定键(只需使用值为“count”的文本)和一个固定值1(与您在wordcount示例中看到的相同) 然后简单地使用一个减速机 作业的输出将是一个带有键“count”的记录,该值是您正在查找的
- 您的映射应该为每个读取的记录发出1
- 您的组合器应该发出它得到的所有“1”的总和(每个贴图的小计)
- 您应该发出记录总数的
您可以选择(显著地!)通过使用与组合器相同的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书籍,并尝试自己编写。这不是一个“别人做我的作业”的网站。优雅而高效的解决方案。