Hadoop Reducer多次接收相同的值,而不是预期的输入
在本地hadoop环境中编写map reduce作业时,我遇到了一个问题,即Reducer没有收到我期望的值。我将问题归结为以下几点: 我创建了一个包含10行的任意输入文件,让map方法执行10次。在映射器中,我创建一个调用计数,并将该计数作为值写入输出,如果值为偶数,则0作为键;如果值为奇数,则1作为键,即以下(键,值)对: (1,1)、(0,2)、(1,3)、(0,4)、(1,5)等 我预计会接到两个打给减速机的电话Hadoop Reducer多次接收相同的值,而不是预期的输入,hadoop,mapreduce,Hadoop,Mapreduce,在本地hadoop环境中编写map reduce作业时,我遇到了一个问题,即Reducer没有收到我期望的值。我将问题归结为以下几点: 我创建了一个包含10行的任意输入文件,让map方法执行10次。在映射器中,我创建一个调用计数,并将该计数作为值写入输出,如果值为偶数,则0作为键;如果值为奇数,则1作为键,即以下(键,值)对: (1,1)、(0,2)、(1,3)、(0,4)、(1,5)等 我预计会接到两个打给减速机的电话 0>[2,4,6,8,10] 1>[1,3,5,7,9] 但是我接到了
- 0>[2,4,6,8,10]
- 1>[1,3,5,7,9]
- 0>[2,2,2,2,2]
- 1>[1,1,1,1,1]
public class TestMapper extends Mapper<LongWritable, Text, IntWritable, IntWritable> {
int count = 0;
@Override
protected void map(LongWritable keyUnused, Text valueUnused, Context context) throws IOException, InterruptedException {
count += 1;
context.write(new IntWritable(count % 2), new IntWritable(count));
System.err.println((count % 2) + "|" + count);
}
}
public class TestReducer extends Reducer<IntWritable, IntWritable, IntWritable, IntWritable>{
@Override
protected void reduce(IntWritable key, Iterable<IntWritable> valueItr, Context context) throws IOException, InterruptedException {
List<IntWritable> values = Lists.newArrayList(valueItr);
System.err.println(key + "|" + values);
}
}
公共类TestMapper扩展了Mapper{
整数计数=0;
@凌驾
受保护的void映射(LongWritable keyUnused、文本值Unused、上下文上下文)引发IOException、InterruptedException{
计数+=1;
write(新的IntWritable(计数%2),新的IntWritable(计数));
System.err.println((计数%2)+“|”+计数);
}
}
公共类TestReducer扩展了Reducer{
@凌驾
受保护的void reduce(IntWritable键、Iterable valueItr、上下文上下文)引发IOException、InterruptedException{
列表值=Lists.newArrayList(valueItr);
System.err.println(键+“|”+值);
}
}
我使用本地测试运行程序运行hadoop作业,如《hadoop:权威指南》(O'Reilly)一书中所述:
公共类TestDriver扩展配置的实现工具{
@凌驾
公共int运行(字符串[]args)引发异常{
如果(参数长度!=2){
System.err.printf(“用法:%s[通用选项]\n”,
getClass().getSimpleName());
ToolRunner.printGenericCommandUsage(System.err);
返回-1;
}
Job jobConf=Job.getInstance(getConf());
setJarByClass(getClass());
jobConf.setJobName(“TestJob”);
setMapperClass(TestMapper.class);
setReducerClass(TestReducer.class);
addInputPath(jobConf,新路径(args[0]);
setOutputPath(jobConf,新路径(args[1]);
jobConf.setOutputKeyClass(IntWritable.class);
jobConf.setOutputValueClass(IntWritable.class);
返回jobConf.waitForCompletion(true)?0:1;
}
公共静态void main(字符串[]args)引发异常{
exit(ToolRunner.run(newtestdriver(),args));
}
打包在一个jar中并使用“hadoop jar test.jar infle.txt/tmp/testout”运行。hadoop在流式传输reducer值时重用value对象 因此,为了捕获所有不同的值,您需要复制:
@Override
protected void reduce(IntWritable key, Iterable<IntWritable> valueItr, Context context) throws IOException, InterruptedException {
List<IntWritable> values = Lists.newArrayList();
for(IntWritable writable : valueItr) {
values.add(new IntWritable(writable.get());
}
System.err.println(key + "|" + values);
}
@覆盖
受保护的void reduce(IntWritable键、Iterable valueItr、上下文上下文)引发IOException、InterruptedException{
列表值=Lists.newArrayList();
for(IntWritable可写:valueItr){
add(新的IntWritable(writable.get());
}
System.err.println(键+“|”+值);
}
谢谢!那是我找不到的地方:)
@Override
protected void reduce(IntWritable key, Iterable<IntWritable> valueItr, Context context) throws IOException, InterruptedException {
List<IntWritable> values = Lists.newArrayList();
for(IntWritable writable : valueItr) {
values.add(new IntWritable(writable.get());
}
System.err.println(key + "|" + values);
}