Weird/Unexpected 我的 map reduce 作业中的输出(1 个额外输出)
Weird/Unexpected output in my map reduce job (1 extra output)
所以我是大数据管理和 hadoop 方面的新手,但即使以我的 java 经验,我也无法理解我的程序的行为。
所以首先我要给出我的代码和我的输入:
这是映射器和缩减器代码。
public class builtdifferent {
public static class mybmapper extends Mapper <LongWritable, Text, Text, Text> {
Text textKey = new Text();
Text textValue = new Text();
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] field = line.split(",");
String name = field[1];
String games = field[8];
String sex = field[2];
String age = field[3];
String team = field[6];
String sport = field[12];
String medal = field[field.length-1];
int gold =0 ,silver = 0, bronze = 0;
if (medal.equals("Gold")|| medal.equals("Silver") || medal.equals("Bronze") || medal.equals("0")) {
if (medal.equals("Gold"))
gold =1 ;
if (medal.equals("Silver"))
silver =1 ;
if (medal.equals("Bronze"))
bronze =1 ;
}
context.write(new Text(name + " " + games + " " + sex ), new Text(age + "," + team + "," + sport + "," + gold + "," + silver + "," + bronze));
}
}
public static class mybreducer extends Reducer<Text, Text, Text, Text> {
Text textValue = new Text();
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
String team="",sport="", age="";
//String test="",test2="";
int mg=0,ms=0,mb=0,a=0;
for (Text value : values) {
String line = value.toString();
String[] aif = line.split(",");
if (aif.length < 6) {
context.write(key, value);
break;
}
age= String.valueOf(aif[0]);
team = String.valueOf(aif[1]);
sport = String.valueOf(aif[2]);
mg+=Integer.valueOf(aif[3]);
ms+=Integer.valueOf(aif[4]);
mb+=Integer.valueOf(aif[5]);
}
a=mg+ms+mb;
textValue.set(age + " " + team + " " + sport + " " + mg + " " + ms + " " + mb + " " + a);
context.write(key,textValue);
}
}
}
这是主要代码。
Configuration conf2 = new Configuration();
Job job2 = Job.getInstance(conf2, "best athletes");
job2.setJarByClass(athletes.class);
job2.setMapperClass(builtdifferent.mybmapper.class);
job2.setCombinerClass(builtdifferent.mybreducer.class);
job2.setReducerClass(builtdifferent.mybreducer.class);
job2.setOutputKeyClass(Text.class);
job2.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job2, new Path(args[0]));
FileOutputFormat.setOutputPath(job2, new Path(args[1]));
System.exit(job2.waitForCompletion(true) ? 0 : 1);
所以基本上我必须处理这种类型的奥林匹克运动员的记录:
ID、姓名、性别、年龄、身高、体重、球队、NOC、比赛、年份、赛季、城市、运动、赛事、奖牌
这是 2 个记录示例:
3,GunnarNielsenAaby,M,24,0,0,Denmark,DEN,1920Summer,1920,Summer,Antwerpen,Football,Football Men's Football,0
4,Edgar Lindenau Aabye,M,34,0,0,Denmark/Sweden,DEN,1900 Summer,1900,Summer,Paris,Tug-Of-War,Tug-Of- War 男子拔河-War,金牌
每个运动员都有很多参赛作品,我需要计算奖牌数并生成如下所示的输出:
键(姓名、游戏、性别)值(年龄、团队、运动、金牌、银牌、铜牌、所有奖牌)
“Andrew William”“Andy”“Stanfield”1952 年夏季 M 24 美国田径运动 2 0 0 2
无论如何,我的代码有效,我得到了我想要的奖牌,但我也得到了一个额外的输出(我需要每个运动员为他参加的每场比赛提供 1 个输出,例如 1964 年夏季一个,1968 年一个 Summer.As 你看我得到 1 个额外的垃圾行,每个正确的行有 4 个零)。
这是我的输出文件的示例(part-r-00000):
“Aagje”“Ada”“Kok (-van der Linden)”1964 年夏季 F 17 荷兰游泳队 0 2 0 2
“Aagje”“Ada”“Kok (-van der Linden)”1964 年夏季 F 0 0 0 0
"Aagje ""Ada"" Kok (-van der Linden)" 1968 年夏季 F 21 荷兰游泳队 1 0 0 1
“Aagje”“Ada”“Kok (-van der Linden)”1968 年夏季 F 0 0 0 0
正如你所看到的,在一个正确的输出之后我得到一个空的,其中有 4 个零和其他数据丢失。
我的 reducer 中有 2 个 context.write 方法,所以我怀疑其中一个是错误的,所以如果我删除 context.write(key, value);
(在 if 内),我只会得到错误的输出(我向您展示了 4 个零)
如果我删除 context.write(key,textValue);
我会得到一个空的输出文件。如果我保留两者,我会得到我向您展示的“奇怪”输出(这是正确的,但也是错误的)。
我还得到一个选项卡,用于分隔输出文件中的键和值
我尽力描述问题,但我真的不明白为什么会发生什么,我希望我能更好地解释它
我真的希望有人能提供帮助,如果这是一个糟糕的问题并且它失败了,我真的很想得到一些关于如何提出更好问题的反馈。
非常感谢!!!!
我实际上找到了答案,我需要在地图函数的开头添加这个 if(((LongWritable)key).get() == 0) { return; }
,在 String line = value.toString();
行上方。
所以我是大数据管理和 hadoop 方面的新手,但即使以我的 java 经验,我也无法理解我的程序的行为。 所以首先我要给出我的代码和我的输入: 这是映射器和缩减器代码。
public class builtdifferent {
public static class mybmapper extends Mapper <LongWritable, Text, Text, Text> {
Text textKey = new Text();
Text textValue = new Text();
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] field = line.split(",");
String name = field[1];
String games = field[8];
String sex = field[2];
String age = field[3];
String team = field[6];
String sport = field[12];
String medal = field[field.length-1];
int gold =0 ,silver = 0, bronze = 0;
if (medal.equals("Gold")|| medal.equals("Silver") || medal.equals("Bronze") || medal.equals("0")) {
if (medal.equals("Gold"))
gold =1 ;
if (medal.equals("Silver"))
silver =1 ;
if (medal.equals("Bronze"))
bronze =1 ;
}
context.write(new Text(name + " " + games + " " + sex ), new Text(age + "," + team + "," + sport + "," + gold + "," + silver + "," + bronze));
}
}
public static class mybreducer extends Reducer<Text, Text, Text, Text> {
Text textValue = new Text();
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
String team="",sport="", age="";
//String test="",test2="";
int mg=0,ms=0,mb=0,a=0;
for (Text value : values) {
String line = value.toString();
String[] aif = line.split(",");
if (aif.length < 6) {
context.write(key, value);
break;
}
age= String.valueOf(aif[0]);
team = String.valueOf(aif[1]);
sport = String.valueOf(aif[2]);
mg+=Integer.valueOf(aif[3]);
ms+=Integer.valueOf(aif[4]);
mb+=Integer.valueOf(aif[5]);
}
a=mg+ms+mb;
textValue.set(age + " " + team + " " + sport + " " + mg + " " + ms + " " + mb + " " + a);
context.write(key,textValue);
}
}
}
这是主要代码。
Configuration conf2 = new Configuration();
Job job2 = Job.getInstance(conf2, "best athletes");
job2.setJarByClass(athletes.class);
job2.setMapperClass(builtdifferent.mybmapper.class);
job2.setCombinerClass(builtdifferent.mybreducer.class);
job2.setReducerClass(builtdifferent.mybreducer.class);
job2.setOutputKeyClass(Text.class);
job2.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job2, new Path(args[0]));
FileOutputFormat.setOutputPath(job2, new Path(args[1]));
System.exit(job2.waitForCompletion(true) ? 0 : 1);
所以基本上我必须处理这种类型的奥林匹克运动员的记录: ID、姓名、性别、年龄、身高、体重、球队、NOC、比赛、年份、赛季、城市、运动、赛事、奖牌
这是 2 个记录示例:
3,GunnarNielsenAaby,M,24,0,0,Denmark,DEN,1920Summer,1920,Summer,Antwerpen,Football,Football Men's Football,0
4,Edgar Lindenau Aabye,M,34,0,0,Denmark/Sweden,DEN,1900 Summer,1900,Summer,Paris,Tug-Of-War,Tug-Of- War 男子拔河-War,金牌
每个运动员都有很多参赛作品,我需要计算奖牌数并生成如下所示的输出: 键(姓名、游戏、性别)值(年龄、团队、运动、金牌、银牌、铜牌、所有奖牌)
“Andrew William”“Andy”“Stanfield”1952 年夏季 M 24 美国田径运动 2 0 0 2
无论如何,我的代码有效,我得到了我想要的奖牌,但我也得到了一个额外的输出(我需要每个运动员为他参加的每场比赛提供 1 个输出,例如 1964 年夏季一个,1968 年一个 Summer.As 你看我得到 1 个额外的垃圾行,每个正确的行有 4 个零)。 这是我的输出文件的示例(part-r-00000):
“Aagje”“Ada”“Kok (-van der Linden)”1964 年夏季 F 17 荷兰游泳队 0 2 0 2
“Aagje”“Ada”“Kok (-van der Linden)”1964 年夏季 F 0 0 0 0
"Aagje ""Ada"" Kok (-van der Linden)" 1968 年夏季 F 21 荷兰游泳队 1 0 0 1
“Aagje”“Ada”“Kok (-van der Linden)”1968 年夏季 F 0 0 0 0
正如你所看到的,在一个正确的输出之后我得到一个空的,其中有 4 个零和其他数据丢失。
我的 reducer 中有 2 个 context.write 方法,所以我怀疑其中一个是错误的,所以如果我删除 context.write(key, value);
(在 if 内),我只会得到错误的输出(我向您展示了 4 个零)
如果我删除 context.write(key,textValue);
我会得到一个空的输出文件。如果我保留两者,我会得到我向您展示的“奇怪”输出(这是正确的,但也是错误的)。
我还得到一个选项卡,用于分隔输出文件中的键和值
我尽力描述问题,但我真的不明白为什么会发生什么,我希望我能更好地解释它 我真的希望有人能提供帮助,如果这是一个糟糕的问题并且它失败了,我真的很想得到一些关于如何提出更好问题的反馈。 非常感谢!!!!
我实际上找到了答案,我需要在地图函数的开头添加这个 if(((LongWritable)key).get() == 0) { return; }
,在 String line = value.toString();
行上方。