hadoop - 读取 csv MapReduce 中的空单元格时的 ArrayIndexOutofBounds

标签 hadoop mapreduce hdfs

我正在尝试为以下数据运行 MapReduce 程序。

enter image description here

这是我的映射器代码:

@Override
protected void map(Object key, Text value, Mapper.Context context) throws IOException, ArrayIndexOutOfBoundsException,InterruptedException {
    String tokens[]=value.toString().split(",");
    if(tokens[6]!=null){
        context.write(new Text(tokens[6]), new IntWritable(1));
    }

}

由于我的一些单元格数据为空,当我尝试读取 Carrier_delay 列时,出现以下错误。请指教。

17/04/13 20:45:29 INFO mapreduce.Job: Task Id : attempt_1491849620104_0017_m_000000_0, Status : FAILED
Error: java.lang.ArrayIndexOutOfBoundsException: 6
    at Test.TestMapper.map(TestMapper.java:22)
    at Test.TestMapper.map(TestMapper.java:17)
    at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:340)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)

enter image description here

Configuration conf = new Configuration();
Job job = Job.getInstance(conf,"IP Access");
job.setJarByClass(Test.class);
job.setMapperClass(TestMapper.class);

job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);

job.setReducerClass(TestReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);

FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);

最佳答案

问题出在行中:if(tokens[6]!=null){

问题是你想取tokens[6]的值,然后检查它是否为null。但是,有些行仅包含六列(第七列为空),因此在这些情况下,tokens 是一个六元素数组。这意味着它包含从 tokens[0]tokens[5] 的值。当您尝试访问 tokens[6] 时,您超出了数组的大小,因此您会遇到 ArrayIndexOutOfBoundsException。

做你想做的事情的正确方法是:

IntWritable one = new IntWritable(1); //this saves some time ;)
Text keyOutput = new Text(); //the same goes here

@Override
protected void map(Object key, Text value, Mapper.Context context) throws IOException, ArrayIndexOutOfBoundsException,InterruptedException {
    String tokens[]=value.toString().split(",");
    if(tokens.length == 7){
        keyOutput.set(tokens[6]);
        context.write(keyOutput, one);
    }

}

更多提示:从你的部分代码来看,我猜你想统计某个特定的载波延迟值出现的次数。在这种情况下,您还可以使用组合器来加速该过程,就像 WordCount 程序所做的那样。您还可以将载波延迟解析为 IntWritable 以节省时间和空间。

关于hadoop - 读取 csv MapReduce 中的空单元格时的 ArrayIndexOutofBounds,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43403788/

相关文章:

java - HDFS 保证从文件读取数据/向文件写入数据

hadoop - 在 hive 中排名

scala - 在另一个数据框中使用一个数据框的列

hadoop - 在另一个盒子中移动 hadoop 主节点 : how to handle HDFS

hadoop - 使用插入覆盖分区的配置单元压缩

java - 每个映射器的多个输入文件 'type'

hadoop - 如何防止 hadoop 损坏的 .gz 文件

caching - 无法访问分布式缓存文件

java - Hadoop MapReduce RecordReader 实现是否必要?

python - 使用REST API为HDFS构建动态UI