mapreduce程序抛出数组索引超出范围的错误

时间:2014-11-03 04:12:18

标签: java apache hadoop mapreduce bigdata

我是MapReduce模型的新手。我试图读取多个文件,这些文件首先用冒号(唯一ID)分隔,然后用逗号分隔的信息如(cust id,int value)。我想解析所有文件并聚合输出文件中唯一id对应的所有cust id和int值。我得到一些数组索引超出限制,我也不知道如何使用我的代码解析所有文件。我应该使用tokenizer迭代值还是Map函数已经这样做了?我的代码如下:

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的建议,感谢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);
    }}}

我可以在控制台上编写任何内容来查看生成输出文件的原因,但它是空的。

2 个答案:

答案 0 :(得分:0)

这是由于存在不良记录而发生的。您的map期待如下输入:

Matrix:Reeves,5

但某个地方的输入文件包含一个没有这两个字符的记录:&amp; ,。空行可能是罪魁祸首。您只需要对拆分数组进行长度检查。而不是直接访问索引,将它们放在验证块中。例如:

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,由于遗留原因,它仍然存在。

答案 1 :(得分:-1)

我刚刚将所有代码置于条件

之内解决了问题
if(input.toString().length() > 0)
{
    <code>
}