2014-09-29 2 views
2

나는 분석하고자하는 특정 지표의 결과를 보여주기 위해 세계 지표 데이터를 가져 오는 mapreduce 프로그램을 만들었습니다. (I.E. CO2 배출). 데이터는 국가, 코드, 표시기, 1 년 배출량, 2 년 배출량 등을 포함하는 긴 줄에 표시됩니다. 내 매퍼에서는 원하는 데이터 만 유지하려고했습니다 (먼저 특정 표시기가있는 경우) 국가 및 모든 배출 수준을 문자열 배열로 유지합니다.MapReduce 빈 출력을 생성하는 프로그램

내 전체 프로그램이 실행되지만 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

디버거를 사용하여 코드를 단계별로 실행하고 단일 입력 집합에 대한 동작을 관찰 해 보았습니까? – voidHead

+0

몇 가지 샘플 입력 텍스트를 제공 할 수 있습니까? – blackSmith

+1

Ur 프로그램이 좋습니다. 나는 문제가 입력에 있다고 생각한다. 아마도 파일의 4 번째 열에는 필수 값이 포함되어 있지 않으므로'if (indicator.equals ("EN.ATM.CO2E.KT")) 조건은 실패합니다. – blackSmith

답변

0

주에서는지도를 가져 오지 않고 줄일 수 있습니다. 수업. 주에 다음을 추가

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

를 샘플 입력에서 내가 토큰이 형식의 6.16E에 있음을 발견 + 03 예외를 던지고 및 정수로 구문 분석 할 수 없습니다 . 또한

, 당신은 당신의에서 System.out.println()가 어디로 가는지를 확인하려는 경우, check this

+1

이 hadoop 포럼의 링크는 stderr이 stdout과 함께 배치되는 장소를 나타내며 나를 도왔습니다 !! –

0

샘플 입력을 분석 한 후, 나는이 문제의 원인을 발견 한 것 같다.

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

5 번째 열에서 모든 숫자 값은 부동 소수점 표현 (예 : '8.44E + 03')에 Mapper의 다음 코드 블록은 잘못된 WRT를 입력이다 그들이 실제로 정수 있지만. 따라서 Integer.parseIntNumberFormatException이되어 작업이 실패합니다. "내 전체 프로그램이 실행됩니다" 문으로 확신 할 수 없습니다 (JobTracker에서 작업 로그를 확인하십시오). 그렇지

levels = (int) Float.parseFloat(tokens[j]); 

더블/플로트 및 감속기 관련된 변경 맵의 출력 값 클래스 FloatWritable/DoubleWritable를 사용하는 levels의 데이터 유형을 변경 : 당신이 입력은 항상 정수를 포함 할 것이라고 확신 경우, 같은 것을 할.

입력에 대한 또 다른 문제점은 구문 분석 중에 NumberFormatException을 생성하는 빈 필드가 있다는 것입니다. 같은 수표를 추가하십시오 :

if (tokens[j] != null || tokens.trim().isEmpty()){ 
     continue; // or do the needful. eg - set levels to 0 or some default value 
    } 

희망이 문제를 해결할 것입니다. 그러나 나는 감속기에서 사용한 논리를 이해할 수 없었습니다.위의 문이있는 쓸모 또는 제가 포인트를 누락 의미

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

을 :이 maxValue & minValue 항상 때문에 비교에 Integer.MAX_VALUE & Integer.MIN_VALUE로 끝납니다 의도적하지만 변수처럼 보인다 수 있습니다. 어쨌든 행운을 빌어 요.

관련 문제