【问题标题】:Parse Flat Json file using MAP Reduce JAVA使用 MAP Reduce JAVA 解析 Flat Json 文件
【发布时间】:2017-11-03 17:10:06
【问题描述】:

我的任务是从 HDFS 解析 Json 对象并写入 HDFS 中的单独文件。以下是我的代码。

package com.main;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.json.JSONException;
import org.json.JSONObject;

public class JsonMain {

    public static class Mapperclass extends Mapper<LongWritable, Text, Text, Text>{

        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException{

            String regId;
            String time;
            String line = value.toString();
            String[] tuple = line.split("\\n");
            try{
                for(int i=0;i<tuple.length; i++){
                    JSONObject obj = new JSONObject(tuple[i]);
                    regId = obj.getString("regId");
                    time = obj.getString("time");
                    context.write(new Text(regId), new Text(time));
                }
            }catch(JSONException e){
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        // TODO Auto-generated method stub

        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "word count");

        job.setJarByClass(JsonMain.class);
        job.setMapperClass(Mapperclass.class);
        //job.setCombinerClass(IntSumReducer.class);        
        //job.setReducerClass(IntSumReducer.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);
    }
}

Flatjson.txt

{"regId":"TbEtvRH""time":1509073895112}
{"regId":"lWJ2u0j""time":1509073905112}
{"regId":"uB9WG5K""time":1509073915112}
{"regId":"9sO7aqg""time":1509073925113}
{"regId":"hguOaKh""time":1509073935113}
{"regId":"p1CAzYt""time":1509073945113}
{"regId":"quDVMkD""time":1509073955113}

注意:我已经在我的项目中包含了所有的依赖Jar。

执行以下命令: hadoop jar JsonMapper.jar com.main.JsonMain /user/cloudera/FlatJson/Flatjson.txt output007

以下是收到的错误消息。

17/11/01 08:11:12 INFO mapreduce.Job: The url to track the job: http://quickstart.cloudera:8088/proxy/application_1509542757670_0003/
17/11/01 08:11:12 INFO mapreduce.Job: Running job: job_1509542757670_0003
17/11/01 08:13:33 INFO mapreduce.Job: Job job_1509542757670_0003 running in uber mode : false
17/11/01 08:13:33 INFO mapreduce.Job:  map 0% reduce 0%
17/11/01 08:15:32 INFO mapreduce.Job: Task Id : attempt_1509542757670_0003_m_000000_0, Status : FAILED

Error: java.lang.ClassNotFoundException: org.json.JSONException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:270)
    at org.apache.hadoop.conf.Configuration.getClassByNameOrNull(Configuration.java:2138)

"java.lang.ClassNotFoundException: org.json.JSONException" ==> 我已经在我的项目中导入了这个 jar。让我知道这有什么问题。

【问题讨论】:

  • 值得指出的是,Apache Spark 或 Drill 可以在不到 5 行代码中解析这个文件
  • @cricket_007=> 上述问题已解决。现在 MR 作业已成功完成,但输出文件创建为空文件。
  • 那么 context.write 从未被击中,而您的 try catch 总是 catched
  • line.split("\\n"); 没有意义,因为默认情况下 MapReduce 总是一次读取一行,因此 for 循环毫无意义
  • @cricket_007 --> 谢谢!我们如何在不循环的情况下读取 Map-reduce 中的 JSON 对象值。请指导我。例如:{"regId":"TbEtvRH""time":1509073895112} 我需要值“TbEtvRH”和“1509073895112”。

标签: java hadoop mapreduce


【解决方案1】:

让我们开始逐步调试您的问题。

  1. 请做一个jar -tvf JsonMapper.jar | grep JSONException 你会看到这个类在你的 jar 中不存在。
  2. 请理解,通过 mvn 之类的依赖管理系统在项目中包含依赖并不能保证其在 jar 中的可用性。
  3. 请使用 shaded 插件将依赖项中的所有 jar 包含到您的 shaded fat jar 中。

【讨论】:

  • jar -tvf JsonMapper.jar | grep JSONException ==> 781 2017 年 11 月 1 日星期三 10:50:28 PDT com/amazonaws/util/json/JSONException.class 807 11 月 1 日星期三 10:50:32 PDT 2017 年 com/cloudera/com/amazonaws/util/json/ JSONException.class 587 2017 年 11 月 1 日星期三 10:50:48 PDT org/json/JSONException.class 700 11 月 1 日星期三 10:50:48 PDT 2017 年 org/json/JSONException.java
【解决方案2】:

"Error: java.lang.ClassNotFoundException: org.json.JSONException" --> 已经解决了。

以前我在 /home/jar/java-json.jar 路径中有 jar。

我已将此 jar 移动到“/usr/lib/hadoop-mapreduce/”此路径并包含此 jar 并将此 jar 添加到它工作的项目中。

cp java-json.jar /usr/lib/hadoop-mapreduce

【讨论】:

    猜你喜欢
    • 2012-03-14
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 2016-08-27
    • 2019-06-09
    • 1970-01-01
    相关资源
    最近更新 更多