【问题标题】:MapReduce Program producing empty outputMapReduce 程序产生空输出
【发布时间】:2014-11-24 11:05:06
【问题描述】:

我创建了一个 mapreduce 程序来获取世界指标数据来显示我想要分析的特定指标的结果。 (即二氧化碳排放)。数据排成一排,包括国家、代码、指标、第 1 年排放量、第 2 年排放量等。在我的映射器中,我试图只保留我想要的数据(首先只保留这条线,如果有特定指标),然后保留国家和所有排放水平(在字符串数组中)。

我的整个程序运行,但我注意到它正在接收 Map 输入记录,但没有 Map 输出记录或 Reduce 输入/输出记录。

我一直想弄清楚我的逻辑哪里出了问题,但我很难过。任何意见表示赞赏。

我的代码如下:

---映射器--

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);

    }
}

【问题讨论】:

  • 您是否尝试过使用调试器单步调试代码并观察其对一组输入的行为?
  • 你能提供一些示例输入文本吗?
  • 你的程序很好。我认为问题在于输入。可能文件的第 4 列不包含所需的值,因此不符合 if(indicator.equals("EN.ATM.CO2E.KT")) 条件。
  • @voidHead 我尝试添加调试器步骤以查看它在我的映射器中停止的位置,但我在编写代码以便能够在我的输出中看到它时遇到问题(即在 if stmt @987654325 @. stmts 没有出现在我的终端中,我仍然没有输出文件。我很难过。
  • @blackSmith 我将文件保存为 .csv 并将其转换为 .txt 下面是示例行,除非您希望我上传更大的示例集。

标签: java apache hadoop mapreduce mapper


【解决方案1】:

从示例输入中我发现令牌的格式为 6.16E+03 抛出异常,无法解析为整数。

另外,如果您想检查 system.out.println() 的去向,check this

【讨论】:

  • 这个hadoop论坛的链接也标明了stderr和stdout一起放的地方,帮帮我!!
【解决方案2】:

在你的主要你没有导入你的地图和减少类。将以下内容添加到 main:

import org.myorg.CO2Mapper;
import org.myorg.CO2Reducer;

【讨论】:

    【解决方案3】:

    分析示例输入后,我似乎找到了问题的原因。 Mapper 中的以下代码块在输入中是错误的:

     for (int j = 4; j < tokenCount; j++){
          levels = Integer.parseInt(tokens[j]);
    

    从第 5 列开始,所有数值都以浮点表示(例如:'8.44E+03'),尽管它们确实是整数。因此Integer.parseInt 正在抛出NumberFormatException 并且作业失败。我不相信 “我的整个程序运行” 语句(检查 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 
      }
    

    希望这能解决问题。但是我无法理解您在减速器中使用的逻辑。这可能是故意的,但由于比较,您的变量 maxValueminValue 将始终以 Integer.MAX_VALUEInteger.MIN_VALUE 结尾:

     maxValue = Math.max(maxValue, val.get());
     minValue = Math.min(minValue, val.get());
    

    这意味着上述陈述是无用的,或者我没有抓住重点。总之祝你好运。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-05
      • 2020-08-05
      • 2017-07-25
      • 1970-01-01
      • 2021-06-17
      • 1970-01-01
      • 2015-08-31
      • 2023-03-22
      相关资源
      最近更新 更多