我创建了一个mapreduce程序,用于获取世界指标数据,以显示我想要分析的特定指标的结果。 (I.E.二氧化碳排放量)。数据的排列很长,包括国家,代码,指示符,第1年排放,第2年排放等。在我的映射器中,我试图只保留我想要的数据(首先只保留行,如果它具有特定指标),然后保持国家和所有排放水平(在字符串数组中)。
我的整个程序运行,但我注意到它正在接收Map输入记录,但是没有Map输出记录或Reduce Input / Output记录。
我一直想弄清楚我的逻辑出错了,但我很难过。任何意见都表示赞赏。
我的代码如下:
--- Mapper--
package org.myorg;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class CO2Mapper extends Mapper <LongWritable, Text, Text, IntWritable>
{
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException
{
String delims = ",";
String splitString = value.toString();
String[] tokens = splitString.split(delims);
int tokenCount = tokens.length;
String country = tokens[1];
String indicator = tokens[3];
int levels;
if(indicator.equals("EN.ATM.CO2E.KT"))
{
for (int j = 4; j < tokenCount; j++)
{
levels = Integer.parseInt(tokens[j]);
context.write(new Text(country), new IntWritable(levels));
}
}
}
}
---- ---减速器
package org.myorg;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class CO2Reducer extends Reducer<Text, IntWritable, Text, IntWritable>
{
@Override
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException
{
int maxValue = Integer.MIN_VALUE;
int minValue = Integer.MAX_VALUE;
for(IntWritable val : values)
{
maxValue = Math.max(maxValue, val.get());
minValue = Math.min(minValue, val.get());
}
context.write(key, new IntWritable(maxValue));
context.write(key, new IntWritable(minValue));
}
}
--- ---主
package org.myorg;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
//import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
public class CO2Levels
{
public static void main(String[] args) throws Exception
{
//with mapreduce
Configuration conf = new Configuration();
Job job = new Job(conf, "co2Levels");
//Job job = new Job();
job.setJarByClass(CO2Levels.class);
//job.setJobName("co2Levels");
job.setMapperClass(CO2Mapper.class);
job.setReducerClass(CO2Reducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setOutputFormatClass(TextOutputFormat.class);
job.setInputFormatClass(TextInputFormat.class);
//job.setInputFormatClass(KeyValueTextInputFormat.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
答案 0 :(得分:1)
从示例输入中我发现令牌的格式为6.16E + 03 这是抛出异常而无法解析为整数。
此外,如果您想检查system.out.println()的位置,check this
答案 1 :(得分:0)
在您的主要内容中,您不会导入地图并减少课程。将以下内容添加到main:
import org.myorg.CO2Mapper;
import org.myorg.CO2Reducer;
答案 2 :(得分:0)
在分析了样本输入后,似乎我找到了问题的原因。 Mapper
中的以下代码块与输入错误:
for (int j = 4; j < tokenCount; j++){
levels = Integer.parseInt(tokens[j]);
从第5列开始,所有数值都以浮点表示(例如:&#39; 8.44E + 03&#39;),尽管它们确实是整数。因此Integer.parseInt
正在抛出NumberFormatException
并且作业失败。我不相信&#34;我的整个程序运行&#34; 语句(检查JobTracker的任务日志)。如果您确定输入将始终包含整数,请执行以下操作:
levels = (int) Float.parseFloat(tokens[j]);
否则将levels
的数据类型更改为float / double,并使用FloatWritable / DoubleWritable作为map的输出值类,并对reducer进行相关更改。
输入的另一个问题是存在空字段,在解析期间也会产生NumberFormatException
。添加一些检查:
if (tokens[j] != null || tokens.trim().isEmpty()){
continue; // or do the needful. eg - set levels to 0 or some default value
}
希望这能解决问题。但是我无法理解你在减速器中使用的逻辑。这可能是有意的,但看起来像你的变量maxValue
&amp; minValue
将始终以Integer.MAX_VALUE
&amp; Integer.MIN_VALUE
由于比较原因:
maxValue = Math.max(maxValue, val.get());
minValue = Math.min(minValue, val.get());
这意味着上述陈述是无用的,或者我忽略了这一点。无论如何祝你好运。