2014-11-03 31 views
0

我對MapReduce模型很陌生。我正嘗試讀取由冒號(唯一ID)首先分隔的多個文件,然後使用逗號分隔的信息(如cust id,int value)。我想解析所有文件,並彙總輸出文件中與唯一標識對應的所有cust id和int值。我得到了一些數組索引,並且我不知道如何使用我的代碼解析所有文件。我應該使用tokenizer來遍歷值或Map函數已經做到了這一點?我的代碼如下:map reduce程序拋出arrayindex出界限錯誤

public static class TokenizerMapper extends Mapper<LongWritable, Text, Text, IntWritable>{ 
int rating = 0; 
Text CustID; 
IntWritable r; 
Text MovieID; 
public void map(LongWritable key, Text line, Context context) throws IOException, InterruptedException { 
     String line1 = line.toString(); 
     String [] fields = line1.split(":"); 
     String Movieid = fields[0]; 
     String line2 = fields[1]; 
     String [] splitline = line2.split(","); 
     String Custid = splitline[0]; 
     int rate = Integer.parseInt(splitline[1]); 
     r = new IntWritable(rate); 
     CustID.set(Custid); 
     MovieID.set(Movieid); 
     context.write(MovieID,r); 

修改後的代碼根據BlackSmith的建議,感謝鐵匠爲您提供的所有幫助。不過,我仍然得到空輸出文件。請建議。

public void map(LongWritable key, Text line, Context context 
       ) throws IOException, InterruptedException { 
     String line1 = line.toString(); 
     String [] fields = line1.split(":"); 
     if(fields.length > 1) 
      { 
      String Movieid = fields[0]; 
      String line2 = fields[1]; 
      String [] splitline = line2.split(","); 
      String Custid = splitline[0]; 
      int rate = Integer.parseInt(splitline[1]); 
      r = new IntWritable(rate); 
      CustID = new Text(Custid); 
      MovieID = new Text(Movieid); 
      context.write(MovieID,r); 
      } 
      else 
      { 
      return; 
      } 
      } 
      } 
     public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> { 
     public void reduce(Text key, Iterable<IntWritable> values, Context context 
        ) throws IOException, InterruptedException { 
    for (IntWritable val : values) { 
    context.write(key, val); 
    }}} 

我可以在控制檯上寫任何東西,看看爲什麼我的輸出文件是生成的,但它是空的。

回答

0

發生這種情況是由於存在不良記錄。你map期待的輸入如下所示:

Matrix:Reeves,5 

但輸入文件包含的某個地方沒有這兩個人物: & ,的記錄。空行可能是罪魁禍首。所有你需要的是分割數組的長度檢查。不是直接訪問索引,而是將它們放入驗證塊中。例如:

String [] fields = line1.split(":"); 
if(fields.length>1){  
    String Movieid = fields[0]; 
    String line2 = fields[1]; 
} else { 
    // initialize Movieid & line2 tosome default value 
    // OR simply put a 'return' statement to skip bad inputs 
} 

splitline陣列必須遵循相同的策略。我認爲你不需要代碼。再次不要使用StringTokenizer,由於遺留原因它仍然存在。

+0

非常感謝BlackSmith。它的工作現在,但生成和空文件。你可以請建議什麼應該是我的減少功能,因爲我的第一步我只想輸出地圖。我試着在代碼下面,但它給出的錯誤:public void reduce(Text key,Iterable values, Context context )throws IOException,InterruptedException context.write(key,values);} – Manvi 2014-11-03 14:47:50

+0

'job.setNumReduceTask(0) '去除減少階段。但是你的問題是你試圖在上下文中寫一個Iterable而不是IntWritable。使用'for(IntWritale val:values){context.write(key,val);}' – blackSmith 2014-11-03 15:16:01